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

为长篇文章道歉,但我试图提供尽可能多的信息 .

我继承了一个使用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-blur调用updateField,并将数据写入数据库 . 这很好用 . 当用户单击text或textedit字段的Clear Field按钮时,数据库中的值将设置回null,但文本框中显示的字符串不会被清除 . 但是,如果我们重新加载表单,则文本字段显示为空 .

起初我认为这与使用ng-repeat产生的领域内的孤立范围有关 . 但是,form.html顶部的attrs.field的简单输出语句显示每次更新文本框时,父作用域也会更新 . 所以这似乎不是问题 .

我已经决定问题可能是输入的$ modelValue正在更新,但$ viewValue不是(或者至少我们需要因为某种原因调用$ render) . 我一直试图将ngModel注入到form.directive.js中,以便访问这些变量和方法,看看我是否正确,但我有一段时间这样做 .

第一次尝试:我尝试将ngModel注入到form.directive.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很新,我发现链接上的信息比较混乱 . 有些人帮助理解他们所谈论的内容会很棒!

第二次尝试:将formMirel作为参数注入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的原因,我发现了这个:Updating ng-model within a directive that uses a template . 我更改了数据:'='范围映射到数据:'= ngModel' . 不幸的是,这根本没有改变任何行为 .

我被卡住了 . 任何人都可以为我提供一些其他途径来探索,或者可以阐明为什么我的包括ngModel失败了吗?

提前致谢!

回答(2)

2 years ago

如果不能看到你实际在做什么,这对于诊断来说绝对是棘手的 . 我会跳过ngModel注射作为危险的过度并发症 . 我猜它实际上是一个简单的核心 .

现在,我在黑暗中拍摄:你是否实际更新了 $scope.data 变量,你从父节点中传递了回调 updateField ,这是在父节点中定义的 . 这意味着当你在函数中引用 $scope.anyVariable 时,它是's referring to the parent' s $scope 元素(你'd be working in the parent controller'封闭,而不是指令的) . 你可以让 updateField 将子范围作为参数,让指令通过它 $scope ,你'd know that you'实际上正在使用正确的 $scope 对象 .

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

2 years ago

所以我们终于解决了这个问题 .

清除字段按钮已包含在Form.html内部,但是在field.html内的字段模板内部输入 . 非常适合不必重复代码,但不幸的是,当我们使用“清除字段”按钮将其设置为空时,这并没有为我们更新输入内部的值 .

为了解决这个问题,我们在每个模板中移动了Clear Field按钮,并在回调周围进行了更改,以便在输入中对ng-model进行的更新转到字段的指令,然后根据需要冒泡到表单的指令 .

这固定(或至少解决了)我们的问题 .

谢谢!