2013-11-02 59 views
1

描述我的問題的最佳方式是演示。這是我想使用我的指令:Angularjs手冊雙向裝訂

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

在哪裏「OBJ」是,我想雙向綁定的範圍的對象。這個問題是我也需要獲取對象'obj'的名稱。

我想出的部分解決方案是將對象('obj')的名稱作爲字符串傳遞並使用$ parse來獲取對象。但是,如果這不會像使用範圍「=」那樣影響$ parent範圍。如何手動編寫雙向綁定,以便對我的作用域上的對象所做的更改將更改父作用域上的對象?

+0

爲什麼只放'obj.name ='thename''並使用'my-attr =「obj」'? –

回答

-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 

這將檢查了作用域鏈,並找到該對象上定義的一個,並修改它。我相信這與使用範圍幾乎完全相同:在指令定義中使用'='。

0

可以使用這個對象的語法:

scope[ attrs.myAttr] 

因爲你沒有在指令

+0

對不起,我應該澄清,我正在使用一個孤立的範圍。 –

+0

如果使用隔離範圍與隔離範圍中的「=」綁定並在mrkup中創建相同的屬性。在jsfiddle.net中創建一個演示程序或顯示你的問題的plunker – charlietfl

+0

我解釋過你試圖避免使用'=',因此試圖避免孤立的作用域 – charlietfl

1

頗經過一番研究,並參照following issue,這裏是一個擴展範圍,允許雙向綁定(它是,從本質上講,角碼,只修改了外出打工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');

+0

您是否更深入地研究了您的解決方案,因爲我目前正在實現'scope。$ bindTwoWay('FormErrors','viewModel.errors');',其中'viewModel'是控制器名稱很少'$ parent''s樹,也沒有你的代碼,也沒有'$ parse'方法,也沒有'$ eval'返回一個值,除了'undefined'給我,就好像引用不存在一樣? – skmasq