1

私の問題を説明する最良の方法は、デモンストレーションを使用することです。これは、ディレクティブを使用する方法です。

<my-directive my-attr="{'property': obj}"></my-directive>

「obj」は、双方向バインディングが必要なスコープ上のオブジェクトです。問題は、オブジェクト「obj」の名前も取得する必要があることです。

私が思いついた部分的な解決策は、オブジェクトの名前 ('obj') を文字列として渡し、$parse を使用してオブジェクトを取得することでした。しかし、スコープ「=」を使用した場合と同じように、これが $parent スコープに影響を与えない場合。スコープ上のオブジェクトへの変更が親スコープ上のオブジェクトを変更するように、手動で双方向バインディングを作成するにはどうすればよいですか?

4

3 に答える 3

1

かなりの調査の後、次の問題を参照して、双方向バインディングを可能にする Scope の拡張を次に示します (これは基本的に Angular コードであり、外部で動作するようにのみ変更されていますnodeLinkFn)。

angular.module('scopeBindExtention', [])

.run( [ '$rootScope', '$parse', function( $rootScope, $parse ) {

    var extended = angular.extend( $rootScope, {} );

    extended.$bindTwoWay = function( scopeName, parentName ) {
        var scope       = this,
            parentScope = scope.$parent;
            lastValue,
            parentGet,
            parentSet,
            compare;

        parentGet = $parse(parentName);
        if (parentGet.literal) {
          compare = angular.equals;
        } else {
          compare = function(a,b) { return a === b; };
        }
        parentSet = parentGet.assign || function() {
          // reset the change, or we will throw this exception on every $digest
          lastValue = scope[scopeName] = parentGet(parentScope);
          throw new Error( "Expression '" + parentName + "' is non-assignable!" );
          /*
          throw $compileMinErr('nonassign',
              "Expression '{0}' is non-assignable!",
              parentName);
          */
        };
        lastValue = scope[scopeName] = parentGet(parentScope);
        var unwatch = parentScope.$watch($parse(parentName, function parentValueWatch(parentValue) {
          if (!compare(parentValue, scope[scopeName])) {
            // we are out of sync and need to copy
            if (!compare(parentValue, lastValue)) {
              // parent changed and it has precedence
              scope[scopeName] = parentValue;
            } else {
              // if the parent can be assigned then do so
              parentSet(parentScope, parentValue = scope[scopeName]);
            }
          }
          return lastValue = parentValue;
        }), null, parentGet.literal);
        scope.$on('$destroy', unwatch);    
    }

}]);

クライアントは以下を呼び出すだけです:

scope.$bindTwoWay( 'childModelName', 'parentModelName' );

于 2014-07-28T15:32:57.107 に答える
-1

私は自分の問題を解決することができました。私の解決策(coffeescriptで):

$scope.$watch name, (val) ->
  scope = $scope.$parent
  # look up the scopes until the real object is found
  while scope isnt null
    if not scope.hasOwnProperty(name)
      scope = scope.$parent
    else
      expressions[name].assign(scope, val)
      scope = null

これにより、スコープのチェーンがチェックされ、オブジェクトが定義されているスコープが見つかり、そこで変更されます。これは、ディレクティブ定義で scope: '=' を使用する場合とほぼ同じ動作だと思います。

于 2013-11-03T07:35:56.890 に答える