如何从外部指令回调方法更改AngularJS指令的隔离范围属性?

时间:2015-12-11 13:20:13

标签: javascript angularjs angularjs-directive scope angularjs-scope

我需要你的帮助! :)

我对AngularJS(v1.2)的开发很陌生,而且我正在玩指令。

问题

我将父ctrl模型attr传递给我的指令,它的内部模型在其独立的范围内。双向数据绑定在父ctrl attr和指令范围attr之间正常工作。

我的问题是我想从父ctrl的外部回调函数更新指令的模型attr,不知道哪个是要更新的父ctrl属性...

这是因为来自我的指令的事件(比如在列表中添加元素)必须执行对REST WS的异步调用以将新元素保存在后端,并使用&#更新angularJS关联模型39;新鲜'响应中收到的数据(例如,我的数据在保存到数据库中后带有ID ...)

重现

我不知道这是否清楚,应该很难理解"因为"所以我做了一个JSFiddle用一个非常基本的例子证明这一点:TEST IT HERE

如果您在" INTERNAL Callback"中键入内容输入文本,您将在指令的范围内调用方法。从异步调用中收到的模型(例如" {id:100,name:' JSFiddle'}")将被设置为指令的内部模型,并反映出来也是父母的范围模型。很好!

但是如果你在" EXTERNAL Callback"中键入内容在输入文本中,您将使用'模型'来调用父控制器范围内的方法。 method属性,它是指令的范围属性。从异步调用接收的模型(例如" {id:100,name:' JSFiddle'}")将被设置为回调方法模型,而不会反映到父& #39;范围模型NOR指令的模型......

我发现的唯一方法是将指令的作用域作为外部回调属性传递,然后在此作用域中更新所需的属性。这样可行,但我认为将整个指令的范围传递给回调方法是奇怪而可怕的......你可以see it in action HERE

当然,您可以告诉我,我只需要在外部回调方法中更新我的父控制器模型,但因为我可以在同一个视图/控制器中使用MANY指令,用于" ng-repeat&# 34;项目,使用相同的回调方法,我无法知道我应该更新哪个父ctrl范围属性... See this case HERE.

有什么想法吗?

示例代码

HTML:

<div ng-controller="MyCtrl">
  <h1>Parent Ctrl</h1>
  <p>ctrlModel.id = {{ctrlModel.id}}</p>
  <p>ctrlModel.name = {{ctrlModel.name}}</p>
  <hr/>
  <h1>Directive</h1>
  <my-directive my-model="ctrlModel" on-change="ctrlOnChange(model)"></my-directive>
</div>

JAVASCRIPT:

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

function MyCtrl($scope, $log) {
    $scope.ctrlModel = {id:0, name:'StackOverflow'};

    $scope.ctrlOnChange = function(paramModel){
        $log.info('MyCtrl.ctrlOnChange / paramModel BEFORE = ' + JSON.stringify(paramModel));
      // Async call to save the model remotely and get it with an ID for example
      /*
      $http.post('/api/save-this-model-please', model)
        .then(function(response){
            model = response.data;
          // Here my LOCAL METHOD model 'paramModel' will be updated with saved data, including an ID !== 0
          // 'ctrlModel' in PARENT scope of 'MyCtrl' AND DIRECTIVE model 'scope.directiveModel' are not synced with these "fresh" data...
        });
      */
      paramModel = {id:100, name:'JSFiddle'};
      $log.info('MyCtrl.ctrlOnChange / paramModel AFTER = ' + JSON.stringify(paramModel));
    };
}

myApp.directive('myDirective', function ($log) {
  return {
    restrict: 'E',
    template: '<div><p>directiveModel.id = {{directiveModel.id}}</p><p>directiveModel.name = {{directiveModel.name}}</p><p>INTERNAL Callback : <input ng-model="directiveModel.name" ng-change="onChangeInternalCallback()"></p><p>EXTERNAL Callback : <input ng-model="directiveModel.name" ng-change="onChangeExternalCallback({model:directiveModel})"></p></div>',
    replace: true,
    transclude: false,

    scope: {
      directiveModel: '=myModel',
      onChangeExternalCallback: '&onChange'
    },

    link: function (scope) { // , element, attrs

    scope.onChangeInternalCallback = function(){
        $log.info('myDirective.onChangeInternalCallback / directiveModel BEFORE = ' + JSON.stringify(scope.directiveModel));
      // Async call to save the model remotely and get it with an ID for example
      /*
      $http.post('/api/save-this-model-please', scope.directiveModel)
        .then(function(response){
            scope.directiveModel = response.data;
          // Here my DIRECTIVE model 'scope.directiveModel' will be updated with saved data, including an ID !== 0
          // With 2-ways data binding, 'ctrlModel' in PARENT scope of 'MyCtrl' is ALSO synced with these "fresh" data...
        });
      */
      scope.directiveModel = {id:100, name:'JSFiddle'};
      $log.info('myDirective.onChangeInternalCallback / directiveModel AFTER = ' + JSON.stringify(scope.directiveModel));
    };

    }

  };
});

0 个答案:

没有答案