隔离指令作用域但保留与ngModel的绑定

4

我有一个指令,将使用ng-model来公开其值。

问题在于,这个指令有一些内部组件也会影响作用域,所以我需要隔离它的作用域,但仍然要保留ng-model与外部世界的绑定。

我应该如何实现这个?

这是指令:

angular.module('app', []).directive('myDirective', function() {
  return {
    restrict: 'E',
    require: 'ngModel',
    link: function(scope, element, attr, ngModel) {
      // do stuff using ngModel controller
    },
    replace: true,
    template: '<div><input ng-model="userInput" /></div>'
  };
});

<my-directive ng-model="prop"></my-directive>

如您所见,指令必须将prop暴露为其值,但不应在父级作用域中暴露在<input ng-model="userInput"/>中定义的userInput
我该如何使只有prop在父级作用域中可用?

你想在指令中如何处理 prop?它会成为一个字段元素的一部分吗?此外,你展示的 ngModel 是用于 prop 还是 userInput - Mark Rajcok
我需要两个 ng-model。其中一个来自输入,将是用户输入的内容。我的指令控制器将 $watch 它的变化,使用 ngModelController.$setViewValue() 补充和更新 prop。我知道我可以监听输入事件并避免内部 ng-model,但在未来,我将有更多的元素共享相同的内部作用域属性。因此,我想要一个隔离的作用域,让内部元素可以玩耍,但仍然希望将 ng-model="prop" 绑定到父作用域。我还将使用外部 ng-model 的有效性功能。 - Caio Cunha
1个回答

3
通常情况下,ngModelController用于指令而不是创建新作用域的指令。我发现在隔离作用域中使用它的唯一方法是使用相同的名称。
scope: { prop: '=ngModel' }  // must use 'prop' here!

更多讨论请看我的SO答案:https://dev59.com/Z2ct5IYBdhLWcg3wsPZ5#14792601

您还可以使用指令使用scope: true创建新作用域。如果这样做,那么prop需要是对象属性而不是原始值,例如:ng-model='someObj.prop'。有关此方法的更多信息,请参见https://stackoverflow.com/a/13060961/215945中的第一个示例。

这仍然允许您在新指令子作用域上创建自己的(新)属性,而不影响父作用域。您需要了解一下作用域原型继承的工作方式 - 在父作用域上定义的对象将在指令子作用域中可见且可更改。在父作用域上定义的原始值将可见,但如果您尝试更改父原始值的值,则会创建一个隐藏/遮蔽同名父属性的子属性。(有关原型继承的更多信息,请参见这里


我知道你提出的双向绑定技巧,但我不能强制用户始终使用相同的属性。我尝试过另一种方法(并且有效),即从外部元素中删除 ng-model 并在模板中定义它,<my-directive some="prop" /> --> scope: {internalBind: '=some'} --> template: <div ng-model="internalBind">...</div>。只是我想让用户明确地使用 ng-model,这样他就知道可以将此元素作为 form 中的控件来使用。 - Caio Cunha
@CaioToOn,只是好奇,你不喜欢scope: true的替代方案吗?(这是我在这里会使用的。)只要使用对象属性(这是Angular团队推荐的方式-即他们建议不要使用原始类型来进行ng-model:[Misko](http://youtu.be/ZhfUv0spHCY?t=30m)。),那么这应该可以给你想要的东西。 - Mark Rajcok
谢谢您的坚持。只是当存在无效值时,将值设置为“undefined”更适合我的设计。我喜欢隔离作用域的想法。不过我开始怀疑我所希望的是否是反模式,或者至少是反自然的,或者这是否是一个常见的需求:能够选择哪些属性通过其属性名与父级保持链接,而无需定义属性名。 - Caio Cunha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接