观看ng-model inside指令

时间:2013-12-29 17:29:21

标签: javascript angularjs angularjs-directive angularjs-scope

我有以下指令:

directive('myInput', function() {
    return {
        restrict: 'AE',
        scope: {
            id: '@',
            label: '@',
            type: '@',
            value: '='
        },
        templateUrl: 'directives/dc-input.html',
        link: function(scope, element, attrs) {
            scope.disabled = attrs.hasOwnProperty('disabled');
            scope.required = attrs.hasOwnProperty('required');
            scope.pattern = attrs.pattern || '.*';
        }
    };
});

使用以下模板:

<div class="form-group">
    <label for="input-{{id}}" class="col-sm-2 control-label">{{label}}</label>
    <div class="col-sm-10" ng-switch on="type">
        <textarea ng-switch-when="textarea" ng-model="value" class="form-control" id="input-{{id}}" ng-disabled="disabled" ng-required="required"></textarea>
        <input ng-switch-default type="{{type}}" ng-model="value" class="form-control" id="input-{{id}}" ng-disabled="disabled" ng-required="required" pattern="{{pattern}}"/>
    </div>
</div>

此表格使用:

<form ng-controller="UserDetailsCtrl" role="form" class="form-horizontal">
    <div ng-show="saved" class="alert alert-success">
        The user has been updated.
    </div>
    <my-input label="First name" value="user.firstName" id="firstName"></my-input>
    <my-input label="Last name" value="user.lastName" id="lastName"></my-input>
    <my-input label="Email" value="user.email" id="email" type="email" disabled></my-input>
    <my-input label="Password" value="user.password" id="password" type="password"></my-input>
    <div class="form-group">
        <div class="col-sm-offset-2 col-sm-10">
            <button ng-click="update()" class="btn btn-default">Save</button>
        </div>
    </div>
</form>

哪个有这个控制器:

controller('UserDetailsCtrl', function($scope, $stateParams, User) {
    $scope.user = User.get({userId: $stateParams.id});
    /**
     * Update the current user in this scope.
     */
    $scope.update = function() {
        console.log($scope.user);
        $scope.user.$update({userId: $scope.user.id}).then(function(results) {
            $scope.saved = true;
        });
    };
}).

表单呈现正常,但是当我单击Save按钮时,用户值永远不会更新。

如何在控制器范围内的myInput指令中使用更新的值?

2 个答案:

答案 0 :(得分:9)

这是基本问题。你的ng-model是一个原语,只是在一个方向上绑定...如果父对象被改变它将更新,但由于它是原始的,它不携带对父对象的引用...只是值。因此,更新原语不会更新它的原始值来自

的父对象
  

角度中的基本规则... 在ng-model中始终有一个点

这是一个将主user对象传递给指令范围的解决方案,以及用于每个输入的该对象的属性

<my-input id="firstName" model="user" field="firstName" label="First name"></my-input>

现在需要将对象从控制器传递到指令范围:

app.directive('myInput', function() {
    return {  
        scope: {
           /* other props*/
            field: '@',
            model:'='/* now have reference to parent object in scope*/
        },
       ......
    };
});

然后在输入的标记中将使用[]表示法来获取

<input  ng-model="model[field]".../>

DEMO

为了使用角度验证,您可能需要require指令中的ngModel控制器或使用嵌套表单

答案 1 :(得分:1)

您的问题是ng-switch

ng-switch这样的{p> ng-repeat会创建一个从父级继承的新范围。

这意味着如果你让我们说:

$ scope.foo =“你好”;

然后你有类似的东西:

<input type="text" ng-model="foo">

ng-switch内。当您更新foo时,它会创建自己的foo隐藏/隐藏父foo

换句话说,输入将显示hello但是当您修改它时,会创建隐藏父项的新foo。这意味着您的父母不会得到更新(您的问题)。

这不是Angular.js问题,这就是Javascript的工作方式。

通常你想做一个:

<input type="text" ng-model="foo.bar">

这样,您可以使用继承,而不是创建新的foo,它只会更新父级的bar

由于这不是你每次都可以做的事情,也许在你的具体用例中你做不到,简单的方法就是使用$parent

<input type="text" ng-model="$parent.value">

在你的ng-switch中,您将直接使用父value

我强烈建议您尽快阅读:https://github.com/angular/angular.js/wiki/Understanding-Scopes

示例:http://plnkr.co/edit/z4D6Gk5fK7qdoh1mndzo?p=preview

干杯。