【问题标题】:angular directives: add DOM elements with ng functions角度指令:使用 ng 函数添加 DOM 元素
【发布时间】:2016-07-20 13:07:03
【问题描述】:

我正在尝试为一个小的输入字段编写一个指令,该输入字段只接受文本并将符号从 searchglass 动态更改为 X,如果里面有文本并在单击时删除该文本。 因此,我将必要的 HTML 添加到输入中,但可以让本机 ng 指令运行。我对角度和希望很陌生,有人可以提供帮助。有一些类似的问题,但没有一个真正有帮助。

angular.module('myApp')
    .directive('searchBox', function ($compile) {
        return {
            restrict: 'A',
            scope: {
                ngModel: '='
            }
            link: function(scope, element, attrs) {
                var appendix = angular.element(
                    '<span class="input-group-addon" ng-click="ngModel = none">' +
                    '  <i ng-hide="ng-model" class="fa fa-search"></i>' +
                    '  <i ng-show="ng-model" class="fa fa-close"></i>' +
                    '</span>');
                var wrapper = angular.element(
                    '<div class="input-group input-group-sm search-box-custom"></div>'
                );
                element
                    .wrap(wrapper)
                    .after(appendix);

                element.removeAttr("search-box"); //prevent endless compile loop
                element.removeAttr("data-search-box"); //prevent endless compile loop*/
                $compile(appendix)(scope);

            }
        };
    });

ng-model 在输入字段中定义

<input search-box
       type="text"
       ng-model-options="{debounce:1000}"
       ng-model="inputValue"
       placeholder="Hier Tippen..." />

编辑:指令应该有一个连接到父范围的自己的范围,但不应该相同,因为在其他情况下父值可能不同

【问题讨论】:

  • 请在使用该指令的地方分享您的 HTML。此外,您最好提供一个 jsFiddle 或 plunker。
  • 添加了输入。 'inputValue' 本身在​​相应的控制器中有它的表示并且工作正常。

标签: javascript angularjs angularjs-directive


【解决方案1】:

请尝试以下代码,它应该可以正常工作。

var appendix = angular.element(
   '<span class="input-group-addon" ng-click="inputValue = null">' +
   '  <i ng-hide="inputValue" class="fa fa-search"></i>' +
   '  <i ng-show="inputValue" class="fa fa-close"></i>' +
   '</span>');

另外,我创建了jsFiddle,请看。

有用信息:

scope 属性可以为真、对象或假值:

  1. falsy:不会为指令创建范围。该指令将使用其父级的作用域。
  2. true:将为指令的元素创建一个原型继承自其父级的新子范围。如果同一元素上的多个指令请求一个新范围,则只会创建一个新范围。新的范围规则不适用于模板的根,因为模板的根总是获得一个新的范围。
  3. {...}(对象哈希):为指令的元素创建了一个新的“隔离”范围。 “隔离”作用域与普通作用域的不同之处在于它在原型上并不从其父作用域继承。这在创建可重用组件时很有用,这些组件不应意外读取或修改父范围内的数据。

默认情况下,不创建范围。这就是您的指令中的情况,这意味着您可以直接从您的自定义指令中访问inputValue

编辑 1

查看jsFiddle 了解详情。主要概念是将modelSettermodelGetter 与有用的函数一起使用:

let modelGetter = $parse(attrs['ngModel']);
let modelSetter = modelGetter.assign;

scope.reset = function () {
    modelSetter(scope, null);
};

scope.isEmpty = function () {
    return !modelGetter(scope);
};

var appendix = angular.element(
    '<span class="input-group-addon" ng-click="reset()">' +
    '  <i ng-show="isEmpty()" class="fa fa-search">Search</i>' +
    '  <i ng-hide="isEmpty()" class="fa fa-close">Delete</i>' +
    '</span>');

【讨论】:

  • 嗨,Alex,谢谢您的回答。实际上,我不想直接访问指令中的父范围以使其保持动态。所以我尝试将scope { ngModel: '=', } 添加到指令中,但它不再起作用了。
  • @Phloppy 请查看编辑1。还有一点需要注意:考虑到它的应用和工作方式,不应将孤立的范围添加到指令中。这就是为什么它在您上面评论中提到的情况下不起作用的原因。
  • 啊,这正是我想要的,非常感谢。我将仔细研究 $parse 的功能以完全理解它。关于这个主题的最后一个问题,我不太清楚:我读了很多,DOM 操作应该只在指令的“编译”部分而不是“链接”部分完成。但是,这不是“包装”和“之后”操作 DOM 吗?只是为了确保最后有干净的角度代码:)
  • @Phloppy 阅读 Angular JS 文档中的以下两篇文章。它应该可以帮助你。 docs.angularjs.org/guide/…, docs.angularjs.org/guide/…
猜你喜欢
  • 1970-01-01
  • 2020-07-17
  • 2015-05-14
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多