AngularJS指令将名称属性绑定到模板元素

angularjs directive binding name attribute to template element

本文关键字:元素 绑定 属性 指令 AngularJS      更新时间:2023-09-26

我正在尝试在选择上创建一个包装器指令,我正在尝试将"名称"属性分配给选择

命令

    <form name=myform>
          <selectformfield label="Select Orders" id="id_1" name="orderselection"
            selectedval="obj.order" options="Orders" />
    </form>

我的指令定义为

mainApp
    .directive(
            'selectformfield',
            function() {
                return {
                    restrict : 'E',
                    transclude : true,
                    scope : {
                        label : '@',
                        id : '@',
                        selectedval : '=',
                        options : '=',
                        name: '='
                    },
                      template : "<select class='form-control'     ng-model='selectedval' name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>"
                };
            });

我正在尝试通过控制器中的 myform 访问选择的名称属性,例如 console.log($scope.myForm.orderselection),但我没有得到定义

如果我在指令中对名称进行硬编码,那么我就可以访问属性控制台.log($scope.myForm.orderselection)

我在这里错过了任何东西。我必须做任何后期编译或其他事情吗?

Khanh TO 是正确的,因为在尝试通过隔离范围访问时,您需要正确设置名称。这是一个我相信你正在努力实现的工作示例。我已经在代码中添加了注释,其中我更改了您所拥有的内容。

普伦克

Javascript:

var app = angular.module('plunker', [])
.controller('MainCtrl', function ($scope, $log) {
    $scope.model = {
        person: {
            name: 'World'
        },
        people: [{
            name: 'Bob'
        }, {
            name: 'Harry'
        }, {
            name: 'World'
        }]
    };
})
.directive('selectformfield', function ($compile) {
    return {
        restrict: 'E',
        replace: true, // Probably want replace instead of transclude
        scope: {
            label: '@',
            id: '@',
            selectedval: '=',
            options: '=',
            name: '@' // Change name to read the literal value of the attr
        },
        // change name='{{ name }}' to be ng-attr-name='{{ name }}' to support interpolation
        template: "<select class='form-control' ng-model='selectedval' ng-attr-name='{{name}}' ng-options='item as item.name for item in options' required><option value=''>-- select --</option></select>"
    };
});

.HTML:

<body ng-controller="MainCtrl">
    <p>Hello {{ model.person.name}}!</p>
     <form name='myForm'>
          <label for='orderselection'>Say hello to: </label>
          <selectformfield label="Select Orders" id="id_1" name="orderselection"
            selectedval="model.person" options="model.people"></selectformfield>
       <p ng-class='{valid: myForm.$valid, invalid: myForm.$invalid }'>The form is valid: {{ myForm.$valid }}</p>
       <p ng-class='{valid: myForm.orderselection.$valid, invalid: myForm.orderselection.$invalid }'>The people select field is valid: {{ myForm.orderselection.$valid }}</p>
    </form>
  </body>

.CSS:

.valid {
  color: green;
}
.invalid {
  color: red;
}

直接在$scope中访问 DOM 是一种不好的做法,应不惜一切代价避免。在像angular这样的MVC结构中,不是访问DOM(视图)来获取其状态和数据,而是访问模型($scope)。在本例中,将指令的名称绑定到父作用域的 orderselection 属性。另请注意,窗体是 FormController 的实例。可以选择使用 name 属性将表单实例发布到范围中。在这种情况下,您可以在父作用域上创建新属性。

如果你在父作用域中,可以尝试像这样访问名称:

console.log( $scope.myform.orderselection );

或者,如果你在指令范围内。

console.log( $scope.name);

由于 scope 指令name属性绑定到父范围orderselection属性,因此需要为父范围属性分配一个值,否则该值将未定义。喜欢这个:

$scope.myform.orderselection = "orderselection ";

如果您需要在指令中进行验证,因为您已经将 name 属性与 orderselection 绑定了 .你可以这样做:

template : "<select class='form-control' ng-attr-name='{{name}}'  ng-disabled='[name].$invalid' .../>