gpt4 book ai didi

javascript - 如何协调 Angular 的 "always use dots with ngModel"规则与隔离范围?

转载 作者:行者123 更新时间:2023-11-29 10:42:17 26 4
gpt4 key购买 nike

我正在使用 Bootstrap 开发 Angular 应用。

为了尽量减少 Bootstrap 在我的 HTML 上的占用空间,我引入了两个表单指令:

form-control.js

module.directive('formControl', function() {
return {
restrict : 'E',
templateUrl : 'form-control.tmpl.html',
scope: {
label: '@'
},
transclude : true
};
});

form-control.tmpl.html

<div class="form-group">
<label class="control-label col-sm-2">
{{ label }}
</label>
<div class="col-sm-10"
ng-transclude>
</div>
</div>

我还对该指令进行了一些“扩展”,用于各种表单输入字段。例如:

表单输入文本.js

module.directive('formInputText', function() {
return {
restrict : 'E',
templateUrl : 'form-input-text.tmpl.html',
scope: {
label: '@',
value: '=ngModel'
}
};
});

form-input-text.tmpl.html

<form-control label="{{label}}">
<input type="text"
class="form-control"
ng-model="value">
</form-control>

app.html

<form-input-text label="Name"
ng-model="person.name">
</form-input-text>

这里我遇到了一个问题。此示例中有许多作用域:

appScope = { person : { name : "John" } };
isolateScope = {
label: "Name",
value: "John" // bound two-way with appScope.person.name
};
transcludeScope = {
__proto__: isolateScope,
label: "Name", // inherited from isolateScope
value: "John" // inherited from isolateScope
};

如果我改变输入文本框中的文本,那么只有transcludeScope被修改:

appScope = { person : { name : "John" } };
isolateScope = {
label: "Name",
value: "John" // bound two-way with appScope.person.name
};
transcludeScope = {
__proto__: isolateScope,
label: "Name", // inherited from isolateScope
value: "Alice" // overrides value from isolateScope
};

这是因为 <input>直接绑定(bind)到 transcludeScope 的属性. transcludeScope.value直接改了,父作用域isolateScope不受影响。因此,输入中的任何模型更改都不会返回到 appScope。 .

我想做的是在 appScope.person.name 之间创建双向绑定(bind)和 isolateScope 的嵌套属性,例如isolateScope.model.value .

理想情况下,我想这样声明我的指令:

表单输入文本.js

module.directive('formInputText', function() {
return {
restrict : 'E',
templateUrl : 'form-input-text.tmpl.html',
scope: {
model: {
label: '@',
value: '=ngModel'
}
}
};
});

这将允许嵌入的部分绑定(bind)到 model.value ,这将使更改对 isolateScope 可见,而 isolateScope 又会在 isolateScope 中传播更改返回appScope .

Angular 似乎不直接支持这种用法。

谁能指出支持此用例的 Angular 功能,或者如果不支持,请提供解决方法?

编辑:

目前,我的解决方案是内联 form-control模板进入 form-input-text模板。

form-input-text.tmpl.html

<div class="form-group">
<label class="control-label col-sm-2">
{{ label }}
</label>
<div class="col-sm-10">
<input type="text"
class="form-control"
ng-model="value">
</div>
</div>

这消除了引入的子范围 ng-transclude ,但它也复制了标记,这是我希望重构到一个地方的。

最佳答案

考虑作用​​域实际上有点走错了路,我认为嵌入与它没有太大关系。要“正确地”执行此操作,您应该与 ngModelController 集成。这允许任何以后集成的解析器和格式化程序(可能包含验证逻辑)在适当的时间运行。这有点复杂,因为你有 2 个:应用程序中的父级和指令模板中的父级,每个都有 2 个“管道”要集成:

  • 模型值(value) -> 观点值(value)
  • View 值 -> 模型值

父 ngModelController 的 View 值然后用作内部 ngModelController 的模型值。所以整体管道看起来像

  • 父模型值 -> 父 View 值 -> 内部模型值 -> 内部 View 值
  • 内部 View 值 -> 内部模型值 -> 父 View 值 -> 父模型值

为此:

  • 确保您在指令定义中require: 'ngModel',以访问父级 ngModelController

  • 从父级 ngModelController 到内部的更改是使用父级 ngModelController$render 方法完成的,使用其 $viewValue。这可确保父级 $formatters 中的任何函数都已运行。

  • 用户从内部指令发起的更改是通过向其 $viewChangeListeners 数组添加一个函数来完成的,该函数调用父 ngModelController 上的 $setViewValue 。要从链接函数范围访问它,您需要一个命名的表单和输入元素。一个小麻烦是,表单仅在指令的链接功能运行后才在指令范围内注册,因此您需要观察者才能访问它。

  • 以防万一,请确保 formInputText 中的模型在一个对象中。 (我不确定这在技术上是否必要)

  • 然后您不需要在内部指令的 scope 对象中拥有模型。

综合来看,

app.directive('formInputText', function() {
return {
restrict : 'E',
templateUrl : 'form-input-text.tmpl.html',
scope: {
label: '@'
},
require: 'ngModel',
link: function(scope, element, attrs, ngModelController) {
scope.model = {};

// Propagate changes from parent model to local
ngModelController.$render = function() {
scope.model.value = ngModelController.$viewValue;
};

// Propagate local user-initiated changes to parent model
scope.$watch('form', function(form) {
if (!form) return;
form.input.$viewChangeListeners.push(function() {
ngModelController.$setViewValue(form.input.$modelValue);
});
});
}
};
});

它的模板看起来像

<form-control label="{{label}}" ng-form name="form">
<input type="text"
class="form-control"
name="input"
ng-model="model.value">
</form-control>

这可以在 http://plnkr.co/edit/vLGa6c55Ll4wV46a9HRi?p=preview 上看到

关于javascript - 如何协调 Angular 的 "always use dots with ngModel"规则与隔离范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26459958/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com