Update scope with satellite data

2019-08-28 11:03发布

问题:

Suppose that you have an array of objects in your scope and that you want to update it with a directive. How can I do that ? I am not really sure what should be done.

The main point is that I want to update the scope with the name and the "satellite data" which is the id in this case but we could imagine that we have more of it.

Question : Why would I need an id value anyway if I don't bother showing it in the UI ? Imagine that instead we are talking to a database and that the database is returning a value based on the input value + the corresponding id. This id will then be used when submitting a form for instance.

One more thing : we don't want to access directly to the people variable from the directive because then the directive wouldn't be general. I have created a plunk here : http://plnkr.co/edit/D2ybe8uPSdzeIxTFzad5

HTML file :

<body ng-controller="MainCtrl">
<span ng-repeat="val in people">
     <input customattr type = "text" ng-model="val.name" />   
    <br /> <br/>  Children :
  <span ng-repeat="v in val.children">
 <input customattr type = "text" ng-model="v.name" />   
  </span>
</span>    
</body>

JS file :

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

app.controller('MainCtrl', function($scope) {
  $scope.people = [{"name":"Toto", "id":1,
    "children": [
      {"name":"John","id":2},
      {"name":"Mary","id":3}      
      ]
    }];

});

app.directive('customattr', function () {
  return {
      restrict: 'A',
      link: function (scope, element, attrs) {
          element[0].onblur = function() {
           console.log("Hello there" + element[0].value);
           // make some magic processing of the input with a XHR request here...
           // for the demonstration the XHR request is replaced by findTheNewDict
           var newDict = findTheNewDict(element[0].value);
           console.log(newDict);
           // Now we want to update the scope with the data
           // How can we do that ?
           scope.$apply(function(s) {
            // We have no knowledge of the variable people here
            // We just know that the data is a dict containing a name and an id
           });
          }              
          findTheNewDict = function(input) {
            // Just a dummy return : it doesn't matter what is returned
            // The main point is that I want to update the right variable
            // in the scope with this data
            return {"name": input + "a", "id":input.length};
          }
      } 

  }; 
});

回答1:

$scope in the controller is what is bound to the view. Assuming your view elements (div etc.) are bound to properties in $scope object, just update the properties like any other JavaScript object and the framework will take care of the rest.

You may have to wrap the update logic around $scope.$apply function depending on where you run it.



回答2:

You appear to be trying to do more than is necessary in your directive. What is 'newDict' for? Why change the id values? Why to the length of the name??!

I added the following line to your plunk, which allows you to see your 'people' object being modified as you type:

<p>{{people}}</p>

Your 'customattr' directive is doing nothing at all, so I didn't use it. You probably want buttons to "Add child" in each "family" and to "Add parent"? They can be in the html with direct function calls to the controller; I added those too.

see: http://plnkr.co/edit/ABaCc8lu5fBJJjpii5LP?p=preview