当前位置: 首页 > 面试题库 >

使用内插名称发布注册表控件

权胜泫
2023-03-14
问题内容

我有以下代码尝试使用进行一些验证样式ng-class

<tr ng-repeat="item in items">
  <td>
    <select name="itemName{{$index}}" ng-model="item.name" ng-options="o for o in nameOptions"
      ng-class="{ 'custom-error': myForm.itemName{{$index}}.$invalid && !myForm.itemName{{$index}}.$pristine }"
      required>
        <option value="">SELECT</option>
    </select>
  </td>
</tr>

我的课程尚未申请,我看不到原因。生成的html符合预期,其名称与ng-class表达式中的对应名称匹配。

当我将其复制到ng-repeat(不$index用于命名)之外时,它可以按预期工作。


问题答案:

发生这种情况的原因是,控件的名称(在其父窗体上注册该控件的名称)是在ngModelController的实例化过程中检索到的,
根据文档
,该名称发生在预链接阶段*之前(因此尚无内插法)。

如果您检查myForm的属性,就会发现它确实具有键为“ itemName {{$ index}}”的属性。

*更新

上的文档 $compile
对于了解是什么使指令滴答作响以及“幕后”发生了什么提供了很好的资源。

简而言之,有两个主要阶段: 编译 阶段和 链接 阶段。

编译
阶段,正在准备模板(例如,可能需要克隆等),并使模板具有Angular意识(例如,编译指令并解析表达式并准备对其进行求值),但它并不限于一个范围(因此没有要评估的范围)。

编译功能用于转换模板DOM。由于大多数指令不执行模板转换,因此不经常使用。需要编译函数的示例是转换模板DOM的指令(例如ngRepeat)或异步加载内容(例如ngView)。

连接 相被进一步分为两个子阶段: 预连接 连接后

在此阶段,作用域起作用,并且name可以根据作用域的属性/函数评估插值表达式(例如,您的属性)。

链接功能负责注册DOM侦听器以及更新DOM。克隆模板后执行。这是放置大多数指令逻辑的地方。

预链接功能
在链接子元素之前执行。执行DOM转换并不安全,因为编译器链接功能将无法找到正确的链接元素。

链接后功能 在链接子元素之后执行。在后链接功能中执行DOM转换是安全的。

因此,在您的情况下,将发生以下情况:

  1. ngModel指令负责在其父表单的上注册该元素FormController,并调用formCtrl.$addControl(modelCtrl);其后链接功能。

  2. FormController使用指定的控制器的$name性能注册控件:
    form[control.$name] = control;

  3. ngModel控制器是的实例的情况下ngModelCntroller,其$name属性定义如下:
    function(..., $attr, ...) { ... this.$name = $attr.name;

  4. 由于控制器是在预链接阶段之前实例化的,因此将$attr.name其绑定到未插值的字符串(即“ itemName {{$ index}}”)。

更新2

现在我们知道了问题所在,继续解决它似乎很合逻辑:)

这是可以解决问题的实现:

  1. 请勿设置name属性,因此不会进行任何注册myForm(我们将手动进行注册)。

  2. 创建一个指令,该指令FormController仅在根据元素的作用域评估表达式之后才将控件注册到父窗体中(让我们调用指令later-name)。

  3. 由于控件是FormController通过控件注册到的ngModelController,因此我们的指令必须(通过其 require 属性)访问这两个控制器。

  4. 在注册控件之前,我们的指令将更新ngModelController$name属性(并在元素上设置名称)。

  5. 我们的指令还必须注意“手动”删除控件(因为我们是手动添加控件)。

非常简单:

<select later-name="itemName{{$index}}"                  <!-- (1) -->

app.directive('laterName', function () {                   // (2)
    return {
        restrict: 'A',
        require: ['?ngModel', '^?form'],                   // (3)
        link: function postLink(scope, elem, attrs, ctrls) {
            attrs.$set('name', attrs.laterName);

            var modelCtrl = ctrls[0];                      // (3)
            var formCtrl  = ctrls[1];                      // (3)
            if (modelCtrl && formCtrl) {
                modelCtrl.$name = attrs.name;              // (4)
                formCtrl.$addControl(modelCtrl);           // (2)
                scope.$on('$destroy', function () {
                    formCtrl.$removeControl(modelCtrl);    // (5)
                });
            }            
        }
    };
});

另请参 见此简短演示



 类似资料:
  • 我有多个主题A、B和C,我正在使用Kafka Streams将它们扇形成主题X。主题A、B和C使用默认主题名称策略在模式注册表中注册为主题。流式传输非常愚蠢,因为它只是将消息扇形,而不确保它们符合注册表中的模式,但它会在消息中添加一个ORIGINAL_TOPIC_NAME标头以指示它来自主题A、B或C。 然后,我让Kafka消费者从主题X中消费。该主题未在模式注册表中注册。Kafka消费者是我使用

  • 我正在使用指标注册表将指标记录到jmx中。我使用以下代码 它第一次运行良好。如果我再次尝试这样做,我得到的错误是一个名为****的度量已经存在。但我想记录发送给控制器的每个请求的相同度量值,以便在Grafana中可视化。 是否有任何方法可以记录每个请求的相同度量名称的值? 还有如何每1分钟检查记录的所有数据点。我们应该对每分钟的值求和吗?我在metrics.xml中有以下内容

  • 有可能从代码发送邮件吗? 我想注册,凭据应该再次发送给用户。 但根本没有电子邮件 我到底做错了什么 这是整个代码 我非常感谢你的帮助 编辑1我将phpmailer添加到我的文件中,并将其加载到代码中,但我如何使用它发送电子邮件?

  • 我正在运行Nexus3.0.1-01,并使用它来托管Maven存储库和NPM注册中心。对于NPM,我有一个npmjs.org的本地镜像,一个本地NPM注册表和一个组合了两者的组... 我一直在npm内部使用它,在那里我可以使用npm-public组作为我的注册表,这一直工作良好。所以,我可以使用Nexus镜像NPMJ。 下一步是使用本地编写的npm模块,并将它们发布到npm-releases(在我

  • 插件要生效, 还需要向Yaf_Dispatcher注册, 那么一般的插件的注册都会放在Bootstra中进行. 一个注册插件的例子如下: 例 7.2. 注册插件 <?php class Bootstrap extends Yaf_Bootstrap_Abstract{ public function _initPlugin(Yaf_Dispatcher $dispatcher) { $user

  • 我已经按照此页上概述的说明,并将本地映像推送到启用注册表插件的本地3节点Minikube集群,并且集群以不安全注册表标志启动,但当我尝试使用映像创建Pod时,我收到以下错误: 正常拉取9m18s(10mx4)kubelet拉取图像"192.168.99.100:5000/myapp: v1" 警告失败9m18s(10mx4)kubelet拉取图像"192.168.99.100:5000/myapp