【问题标题】:How to access input elements through the angularjs forms collection that are encapsulated in a directive如何通过封装在指令中的 angularjs 表单集合访问输入元素
【发布时间】:2014-05-30 03:25:01
【问题描述】:

我需要访问表单集合的输入元素来进行一些自定义验证。这工作得很好: scope.myForm.value3.$setValidity('complex', valid); 直到我将 value3 转换为一个指令,该指令又包含名为 value3 的输入元素。现在我无法再访问指令的底层输入元素了。

重要代码如下(working plunker here):

<form name="myForm" two-values>
      <input id="value1" name="value1" ng-model="f.v1"/>
      <input id="value2" name="value2" ng-model="f.v2"/>
      <szp-input id="value3" value="f.v3"></szp-input>
</form>

app.directive('twoValues', function ($parse) {
    function isValid(scope, value1, value2) {
        var valid = true;
        if (value1 == 0 && value2 == 0) {
            valid = false;
        } else if (value1 != 0 && value2 != 0) {
            valid = false;
        }
        console.log(scope.myForm);
        // note that I can access value1 and value2, but not value3
        // which is encapsulated in a directive
        scope.myForm.value1.$setValidity('complex', valid);
        scope.myForm.value2.$setValidity('complex', valid);
        // this throws and error saying that value3 is undefined 
        scope.myForm.value3.$setValidity('complex', false);
    }

    return {
        restrict: 'A',
        replace: true,
        link: function (scope, elem, attr, ctrl) {
            scope.$watch('f.v1', function () {
                isValid(scope, scope.f.v1, scope.f.v2);
            });
            scope.$watch('f.v2', function () {
                isValid(scope, scope.f.v1, scope.f.v2);
            });
        }
    };
});

【问题讨论】:

    标签: javascript angularjs angularjs-directive


    【解决方案1】:

    这与 szpInput 指令在 form 指令完成工作后如何完全编译/链接有关。我在您的代码版本中注意到的是,表单确实具有您的自定义值,但它存储为 myForm.{{id}},这告诉我们 form 在 AngularJs 能够将 {{id}} 的值嵌入到名称属性。

    我如何让它工作是通过将函数传递给指令中的template 属性,而不是使用templateUrl。在模板函数中,我正在构建您的模板并为nameid 属性设置实际值。

    app.directive('szpInput', function ($timeout) {
    
        return {
            restrict: 'E',
            replace: true,
            scope: {
                id: "@id",
                value: "=value"
            },
            template: function(elem,attrs) {
              var elemTpl = '<input type="text"'
                + ' ng-model="value"' 
                + ' id="' + attrs.id + '"'
                + ' name="' + attrs.id + '"'
                + ' class="form-control input-sm"/>';
              return elemTpl;
            }
        };
    });
    

    这是updated plunker

    我感觉类似的事情可以通过使用complile 和/或$complile 服务来完成,但我不太熟悉如何最好地使用它们。

    【讨论】:

    • 所以,你基本上说我应该转储 templateUrl 并改用模板。它似乎确实有效,但是伙计,它很丑陋。讨厌使用 html 代码作为字符串。我真的很想将 html 放在一个单独的文件中。
    猜你喜欢
    • 2013-11-19
    • 2018-01-20
    • 2011-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    • 2016-08-07
    • 1970-01-01
    相关资源
    最近更新 更多