7

我正在尝试在 select 上创建一个包装器指令,并且我正在尝试将“name”属性分配给 select

指示

    <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) 我得到未定义

如果我在指令中硬编码名称,那么我可以访问属性 console.log($scope.myForm.orderselection)

我在这里缺少任何东西。我必须做任何后期编译吗?

4

2 回答 2

5

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;
}
于 2013-10-19T05:36:24.780 回答
0

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

如果您在父范围内,您可以尝试访问这样的名称:

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

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

console.log( $scope.name);

因为您的范围指令name属性绑定到您的父范围orderselection属性,所以您需要为您的父范围属性分配一个值,否则它将是未定义的。像这样:

$scope.myform.orderselection = "orderselection ";

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

template : "<select class='form-control' ng-attr-name='{{name}}'  ng-disabled='[name].$invalid' .../>
于 2013-10-19T03:40:13.183 回答