pussmun
pussmun

Reputation: 143

Ng-controller on same element as ng-repeat - no two-way-data-binding

I can't get two-way-data-binding to work in an Angular js ng-repeat. I have an ng-controller specified on the same element that has the ng-repeat specified - I just learnt that by doing this, I can get a hold of each item that is being iterated over by ng-repeat. Here is the HTML:

<div ng-controller="OtherController">
  <div id="hoverMe" ng-controller="ItemController" ng-mouseenter="addCaption()" 
    ng-mouseleave="saveCaption()" ng-repeat="image in images">
    <div class="imgMarker" style="{{image.css}}">                           
      <div ng-show="image.captionExists" class="carousel-caption">
        <p class="lead" contenteditable="true">{{image.caption}}</p>
      </div>
    </div>
  </div>
</div>

And here is the ItemController:

function ItemController($scope){
  $scope.addCaption = function(){
    if($scope.image.captionExists === false){
      $scope.image.captionExists = true;
    }
  }
  $scope.saveCaption = function(){
    console.log($scope.image.caption);
  }
}

And the OtherController:

function OtherController($scope){
  $scope.images = ..
}

When I hover the mouse over the #hoverMe-div - the caption-div is added correctly. But when I input some text in the paragraph and then move the mouse away from the #hoveMe-div, the $scope.image-variables caption value is not updated in the saveCaption-method. I understand I'm missing something. But what is it?

Upvotes: 0

Views: 1302

Answers (2)

tasseKATT
tasseKATT

Reputation: 38490

You don't need a ng-controller specified on the same element that has the ng-repeat to be able to get each item.

You can get the item like this:

<div ng-repeat="image in images" ng-mouseenter="addCaption(image)" ng-mouseleave="saveCaption(image)" class="image">

And in your controller code:

$scope.addCaption = function (image) {
    if(!image.captionExists){
      image.captionExists = true;
    }
}; 

To get contenteditable to work you need to use ng-model and a directive that updates the model correctly.

Here is a simple example based on the documentation:

app.directive('contenteditable', function() {
  return {
    require: 'ngModel',
    link: function(scope, element, attrs, controller) {

      element.on('blur', function() {
        scope.$apply(function() {
          controller.$setViewValue(element.html());
        });
      });

      controller.$render = function(value) {
        element.html(value);
      };
    }
  };
});

Note that the directive probably needs more logic to be able to handle for example line breaks.

Here is a working Plunker: http://plnkr.co/edit/0L3NKS?p=preview

Upvotes: 1

Chandermani
Chandermani

Reputation: 42669

I assume you are editing the content in p contenteditable and are expecting that the model image.caption is update. To make it work you need to setup 2 way binding.

2 way binding is available for element that support ng-model or else data needs to be synced manually. Check the ngModelController documentation and the sample available there. It should serve your purpose.

Upvotes: 0

Related Questions