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 回答
0

可以使用这个对象语法:

scope[ attrs.myAttr] 

访问父范围属性,因为您没有在指令中使用隔离范围

于 2013-11-02T22:41:24.827 回答
-1

我设法解决了我的问题。我的解决方案(在咖啡脚本中):

$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 回答