Search code examples
angularjsangularjs-directiveangularjs-service

two-way binding in directive, model from service non-assignable


I am getting the following error: "Expression '{0}' used with directive '{1}' is non-assignable!", as can be shown here: https://docs.angularjs.org/error/$compile/nonassign

Edit: Having moved the config object into the scope this part is resolved, however the models are still not bound as expected. http://plnkr.co/edit/AVs2IW75oWavpsPNDgnb?p=preview

Old plunker: http://plnkr.co/edit/AVs2IW75oWavpsPNDgnb?p=preview (Try and edit a field and check the console)

I don't really understand the problem which is why that link can't help me to solve it. I am using a directive to bind data, and the data that is being "bound" is actually pointing to a service.

<multi-edit model="profileService.current" config="{
    title: 'Edit profile description', 
    fields: [
    {name: 'Title', model: profileService.current.title, input: true}, 
    {name: 'Description', model: profileService.current.description, textarea: true}
]}">
  CLick me
</multi-edit>

So I am trying to edit profileService.current.title for example, by using the ng-model config.fields[0].model. It can read the data correctly, but not write to it. What do I need to do in order to be able to write to the correct models?


Solution

  • UPDATED

    You should use a scope model for "config".

    Put this in your main controller:

    $scope.config = {
      title: 'Edit profile description',
      fields: [{
        name: 'Title',
        model: 'title',
        input: true
      }, {
        name: 'Description',
        model: 'description',
        textarea: true
      }]
    };
    

    and then in your main HTML:

    <multi-edit model="profileService.current" config="config">
      CLick me
    </multi-edit>
    

    Then, in your directive HTML:

    <li ng-repeat="(key, value) in config.fields">
        <input ng-if="value.input" type="text" ng-model="model[config.fields[key].model]" />
        <textarea ng-if="value.textarea" type="text" ng-model="model[config.fields[key].model]"></textarea>
    </li>
    

    See the updated plunker.