文本框未更新指令中显示的值

Text box not updating displayed value from directive

本文关键字:显示 指令 更新 文本      更新时间:2023-09-26

很抱歉发了这么长的帖子,但我正在尽可能多地提供信息。

我继承了一个使用Angular的相当复杂的应用程序。由于NDR的原因,我无法发布代码示例,而且到目前为止,我还无法在一个较小、不那么复杂的独立plnkr中重新创建我的问题。我相信如果可以的话,我可以想办法解决这个问题。我知道你的手被束缚了,因为我不能发布代码,也不能在plnkr中重新创建问题,但我会尽我所能提供尽可能多的信息,希望能得到一些关于下一步要看什么的一般建议。

首先,代码/体系结构:我有一个form.html。在这个form.html中,我们使用ng repeat迭代从数据库中提取的字段列表,并显示每个字段。表单级别的字段是自定义类型。

<field data=“attrs.field[fieldId]” on-update”updateField” field=“field"></field>

updateField(fieldId,data)在form.directive.js中定义,用于在数据更改时将数据更新回数据库。这部分工作可靠。

form.html还包含一个用于清除字段内容的按钮。

<button class="btn btn-sm btn-danger" tooltip="Clear Field" ng-click="updateMetadataField(field._id, null)" ng-show="field.editable">

该字段使用模板根据类型生成正确的输入。我们使用选择、文本、文本编辑和许多其他自定义字段。我们在这些领域中也使用了预测文本。

这里有一个例子:

<input name={{field._id}} type="text" class="form-control" ng-model="data" ng-blur="onUpdate(field._id, data)" ng-if="field.editable" typeahead="suggestion as suggestion for suggestion in field.suggestions | filter:$viewValue | limitTo:8" />

有一个field.directive.js,它有自己的方法,用于操作已编写的自定义输入字段。其中包括:

scope: {
  data: '=',
  field: '=',
  onUpdate: '='
},

问题是:在最初加载表单时,如果文本字段中有数据,并且用户单击"清除字段"按钮,则数据库将更新,字符串将从文本框中删除。

当用户首先在字段中键入文本,然后离开该字段时,ng-flur调用updateField,数据就会写入数据库。这很好用。当用户单击文本或文本编辑字段的"清除字段"按钮时,数据库中的值会被设置回null,但文本框中显示的字符串不会被清除。但是,如果我们重新加载表单,文本字段将显示为空。

起初,我认为这与使用ng重复产生的字段内部的孤立范围有关。然而,form.html顶部attrs.field的一个简单输出语句显示,每次更新文本框时,父作用域也在更新。所以这似乎不是问题所在。

我已经决定,也许问题是输入的$modelValue正在更新,但$viewValue没有更新(或者至少出于某种原因,我们需要调用$render)。从那以后,我一直试图将ngModel注入form.directive.js中,以便访问这些变量和方法,看看我是否正确,但我做这件事的时间很长。

第一次尝试:我尝试将ngModel注入到form.directory.js指令的参数列表中。当我加载表单时,我得到以下错误:

Error: [$injector:unpr] Unknown provider: ngModelProvider <- ngModel <- fieldsDirective
http://errors.angularjs.org/1.4.7/$injector/unpr?p0=ngModelProvider%20%3C-%20ngModel%20%3C-%20fieldsDirective

我是Angular的新手,我发现链接中的信息相当混乱。如果能理解他们在说什么,那就太棒了!

第二次尝试:将ngModel作为参数注入form.directive.js中链接字段中的函数,并在return{}节中插入require:"ngModel"语句。当我加载表单时,我得到以下错误:

Error: [$compile:ctreq] Controller 'ngModel', required by directive ‘fields', can't be found!
http://errors.angularjs.org/1.4.7/$compile/ctreq?p0=ngModel&p1=fields

当我点击这个链接时,它表示它正在当前DOM元素或其祖先上寻找所需的指令控制器(当使用require:'^ngModel'时)。然而,表单中使用的字段中的模板正在使用这些模板。这是否符合以这种方式在当前DOM元素中使用的条件?

第三次尝试:假设模板是我不能包含ngModel的原因,我发现:在使用模板的指令中更新ngModel。我已将数据"="范围映射更改为数据"=ngModel"。不幸的是,这根本没有改变任何行为。

我被卡住了。有人能为我提供一些其他探索的途径吗?或者也许能解释为什么我的including ngModel失败了?

提前感谢!

如果不能看到您实际在做什么,诊断起来肯定很棘手。我会跳过ngModel注射,因为它比并发症更危险。我想这其实是一件简单的事情。

现在,我在黑暗中的镜头:你真的在更新你试图使用的$scope.data变量吗?在我看来,您正在从父级传递回调updateField,该回调在父级中定义。这意味着,当您在函数中引用$scope.anyVariable时,它指的是父控制器的$scope元素(您将在父控制器的闭包中工作,而不是指令的)。您可以让updateField将子作用域作为参数,让指令将其$scope传递给它,这样您就知道您实际上使用的是正确的$scope对象。

当绑定到ngModel的实际变量被正确修改时,显示应该依次更改。

所以我们最终解决了这个问题。

Clear Field按钮包含在Form.html中,但作用于Field.html中字段模板中的输入。这很好,不必重复代码,但不幸的是,当我们使用Clear Field按钮将其设置为null时,这并没有更新输入中的值。

为了解决这个问题,我们在每个模板内部移动了"清除字段"按钮,并在回调周围进行了更改,以便对输入中的ng模型进行的更新转到字段的指令,然后根据需要弹出到表单的指令。

这解决了(或者至少解决了)我们的问题。

谢谢!