0

看那个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双向绑定中以我期望的方式工作时。

查看工作演示

<body ng-controller="MainCtrl">

    {{ obj.name }}

    <dir>
      <input type="text" ng-model="obj.name" />
    </dir>

  </body>

这种行为的解释是什么?

4

3 回答 3

2

从子作用域访问父作用域上的原始变量存在问题。您有一个子范围,因为transclude: true创建了一个新范围。

您真的应该阅读这篇文章以深入了解正在发生的事情。

文章的亮点:

范围继承通常很简单,而且您通常甚至不需要知道它正在发生...直到您尝试将 2 路数据绑定(即表单元素、ng-model)到一个基元(例如,数字、字符串、 boolean) 在子范围内的父范围上定义。

通过遵循始终使用“.”的“最佳实践”,可以轻松避免原语的这个问题。在您的 ng 模型中。

发生的情况是在涉及原语时不咨询父范围。这是一个 Javascript 的东西,甚至不是 Angular 的。

我还创建了一个隐藏在子范围内的对象的演示。(阴影一个非原始对象):

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"}; 
        }

    };
});
于 2015-02-13T16:13:49.403 回答
0

嵌入的 html 会MainCtrl在编写此新属性 ( obj) 时生成一个子作用域,子作用域会生成一个覆盖父作用域的新作用域。

不参考原型链,在 childScope 中添加了一个新的 aString 属性。这个新属性隐藏/隐藏同名的 parentScope 属性。

修改后的版本有效,因为子范围(转入)首先访问 obj(引用),然后访问属性名称

在https://github.com/angular/angular.js/wiki/Understanding-Scopes了解有关范围继承的更多信息

以及http://angular-tips.com/blog/2014/03/transclusion-and-scopes/的嵌入和范围行为

于 2015-02-13T16:43:05.313 回答
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>

于 2015-03-03T23:21:13.550 回答