让angularjs指令工作

时间:2014-07-15 01:07:27

标签: angularjs angularjs-directive

新手试图了解有关指令的更多信息。想要一个将红色星号放在标签前面的指令,但只有当label的输入具有必需属性时才会这样。

我一直在努力的小提琴就在这里。 http://jsfiddle.net/NYNYM/1/

这是HTML

<body data-ng-app="TestLabel">

    <div class="container">
        <div class="row" >
            <form name="TestLabelForm" class="form-horizontal">
                <div class="form-group">
                    <jcdc-input-label for="Simple" size="col-md-7" text="Test Label"></jcdc-input-label>
                    <input type="text" name="Simple" required="" />
                </div>
            </form>
        </div>
        <br/>
            Should look like
        <br />

        <div class="row">
            <form name="ExampleForm" class="form-horizontal">
                <div class="form-group">
                    <label for="Simple2" class="col-md-7"><span style="color:red">*</span>Test Label:</label>
                    <input type="text" name="Simple2" required="" />
                </div>
            </form>
        </div> 
    </div >

    <!-- Get Javascript -->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js" >
    </script >
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.min.js" > </script > 
    <script src="js/TestLabel.js" > </script > 
</body > 

这是JavaScript

(function() {
    'use strict';

    var app = angular.module('TestLabel', []);

    app.directive('jcdcInputLabel', function () {
        return {
            restrict: 'E',
            template: '<label class="control-label {{size}}" for="{{for}}"><span ng-show="ShowRequired">*</span>{{text}}:</label>',
            replace: true,
            scope: {
                size: '@',
                text: '@',
                for: '@'
            },
            link: function ($scope, el, attrs) {
                scope.ShowRequired = false;

                var fieldName = attrs['for'];
                var inputArray = document.FindByName(fieldName);
                scope.ShowRequired = inputArray[0].hasAttribute("required");


            }
        };
    });

})();

非常感谢您提供的任何帮助。

3 个答案:

答案 0 :(得分:0)

让它为你工作at this fiddle ...这就是你错过的。

1。更换时,请勿手动复制属性。

就像Jason Goemaat所说,angular会为你复制它们,所以手动添加它们会给你Simple Simple。只需将for="..."放入模板即可。

2。它是document.getElementsByName()

据我所知,

document.FindByName在任何浏览器中都不存在。请改为getElementsByName()

3。观察您的变量名称

像杰森说的那样,你有$scopescopelink函数不使用注入,这就是为什么你会看到人们在那里使用常规scope来表示这一点,所以我会遵循这个例子。

4。实际上不要为此

使用指令

像charlietfi所说,这不是指令的一个很好的用例。这对学习有好处,但是你会发现使用jQuery或文档方法必须在外部触及的指令是反角的,会引起巨大的麻烦。
这并不是说这是一个糟糕的开始,但是为了让它更好,尝试将<input>移动到你的模板中,因为这个指令反正要求<input>;它将使您更容易在代码中找到输入,并使您的指令更有用。

答案 1 :(得分:0)

而不是修复你的代码,我只是要引导你创建一个完成你的目标的指令。首先,我认为将输入作为指令的一部分包含在内更有意义。这将是一个简洁的小指令,它将标签的文本作为属性,如果指令的使用者包含required属性,则显示星号。请记住,虽然@charlietfl不是很有礼貌,但他说这个指令有点过分是正确的。这仅用于学习目的。

让我们点击一​​个快速的线框指令,除了模板之外什么都没有,所以我们可以谈谈它。

var app = angular.module('TestLabel', []);

app.directive('labeledInput', function () {
    return {
        restrict: 'E',
        template: [
            '<div>',
            '    <span ng-show="ShowRequired">*</span>',
            '    <label for="{{id}}">{{labelText}}</label>',
            '    <input type="text" id="{{id}}" />',
            '</div>'
        ].join(''),
        replace: true,
        link: function (scope, element, attributes) {

        }
    };
});

你已经可以看到我已经修改了一点模板。通常我会单独包含模板,但是对于这个例子,我将它放入一个数组中,然后使用数组的join方法将所有标记字符串连接成一个字符串。我发现当没有任何好的替代品时,这种技术使得标记字符串更容易阅读。请记住,在现实世界中,您需要引用您的模板,该模板将存储在其他位置,最好是在您的编辑器可以进行语法突出显示的位置以及您习惯的其他好东西。

现在让我们继续并定义我们的隔离范围。

app.directive('labeledInput', function () {
    return {
        restrict: 'E',
        template: [
            '<div>',
            '    <span ng-show="ShowRequired">*</span>',
            '    <label for="{{id}}">{{text}}</label>',
            '    <input type="text" id="{{id}}" ng-model="model" />',
            '</div>'
        ].join(''),
        replace: true,
        scope: {
            id: '@',
            text: '@',
            model: '=',
        },
        link: function (scope, element, attributes) {

        }
    };
});

在这里,我继续为隔离范围添加了三个属性。第一个是id,我只是将其转移到标签的for属性和输入的id属性中。接下来我有text,它只不过应该在标签上显示的文字。最后我有model。我从我们的作用域中提供model到我们模板中的ng-model指令,允许输入双向绑定到我们的作用域属性model,它与任何外部作用域双向绑定用户在使用指令时包含在model属性中的属性。等号是指定属性应该与提供的外部作用域属性双向绑定的内容。

现在让我们填写我们的链接功能,让神奇的事情发生。

app.directive('labeledInput', function () {
    return {
        restrict: 'E',
        template: [
            '<div>',
            '    <span ng-show="required">*</span>',
            '    <label for="{{id}}">{{text}}</label>',
            '    <input type="text" id="{{id}}" ng-model="model" />',
            '</div>'
        ].join(''),
        replace: true,
        scope: {
            id: '@',
            text: '@',
            model: '=',
        },
        link: function (scope, element, attributes) {
            scope.required = attributes.hasOwnProperty('required');
        }
    };
});

更简单的是吗?我们没有通过使用隔离范围语法传递required的原因是因为我们只想查看属性是否包含在内并且我们不关心它的值。现在,用户只需将单词required放在指令上,就会显示星号。

<div ng-controller="MainController">
    <labeled-input id="requiredInput" text="Required Input:"  model="requiredValue" required></labeled-input>
    Required Value: {{ requiredValue }}
</div>

工作演示:http://plnkr.co/edit/hnkA6xFzcg06Xloxgzks?p=preview

答案 2 :(得分:0)

我认为您需要更改指令

myApp.directive('inputrequired', function ($compile) {
    return {
        restrict: 'A',
        replace: true,
        scope: {
            lableText: '@',
            text: '@',
            for: '@'
        },
        link: function (scope, element, attrs) {
           if(attrs['required'] &&  attrs['type']=="text")
           {

               var html ='  <label for="Simple2" class="col-md-7"><span style="color:red">*</span>Test Label:</label><input type="text" name="Simple" required/>';
        var e =$compile(html)(scope);
        element.replaceWith(e);    
           }


        }
    };
});

Working Demo