查看DEMO
<body ng-controller="MainCtrl">
{{ obj }}
<dir>
<input type="text" ng-model="obj" />
</dir>
</body>
为什么当我使用obj
更改自定义指令中的ng-transclude
范围变量时,我不会在MainCtrl
$scope.obj
中更改它。
但是当我在$scope.obj = { name : 'test' };
中MainCtrl
时,双向绑定按照我期望的方式工作。
查看工作DEMO
<body ng-controller="MainCtrl">
{{ obj.name }}
<dir>
<input type="text" ng-model="obj.name" />
</dir>
</body>
这种行为有什么解释?
答案 0 :(得分:2)
从子作用域访问父作用域上的原始变量存在问题。您有一个子范围,因为transclude: true
创建了一个新范围。
你真的应该阅读this article以深入了解正在发生的事情。
文章的重点:
范围继承通常是直截了当的,你通常不会 甚至需要知道它正在发生......直到你尝试双向数据绑定 (即表格元素,ng-模型)到基元(例如,数字,字符串, boolean)在子范围内从父范围定义。
和
通过遵循以下内容,可以轻松避免使用原语这个问题 &#34;最佳实践&#34;总是有一个&#39;。在您的ng模型中。
当涉及到基元时,不会查询父作用域。它是一个Javascript的东西,甚至不是Angular的。
我还创建了一个隐藏子范围的Demo对象。 (遮蔽非原始对象):
app.directive('dir', function () {
return {
restrict: 'E',
scope: true,
template: "<div><input type=\"text\" ng-model=\"obj.name\" /></div>",
link: function(scope, element, attrs) {
scope.obj = {name : "newname"};
}
};
});
答案 1 :(得分:0)
当写入这个新属性(MainCtrl
)时,被转换的html会生成obj
的子范围,子范围会生成一个覆盖父级的新范围。
不会查询原型链,并且会向childScope添加新的aString属性。这个新属性使用相同的名称隐藏/隐藏parentScope属性。
修改后的版本有效,因为子范围(transcluded)首先访问obj(引用),然后访问属性名称
详细了解https://github.com/angular/angular.js/wiki/Understanding-Scopes
的范围继承http://angular-tips.com/blog/2014/03/transclusion-and-scopes/
处的翻译和范围行为答案 2 :(得分:0)
当您从同一范围查询obj
的值时,这是有效的 - 指令的范围:
<body ng-controller="MainCtrl">
{{ obj }}
<dir>
<p>
The following text will be synched with the model:
</p>
<span>{{ obj }}</span>
<br/>
<input type="text" ng-model='obj' />
</dir>
</body>