Can someone help me understand two confusing behaviors in my code:
- I have a formatter in the directive array-to-string that is only triggered during initialization. When I update the array in my Controller with the push function, the formatter doesn't get invoked. Why is this happening and how can I fix it?
- In the formatter function of the array-to-string directive, I extract values from an array into a single string and return it. However, the ng-model of mydir doesn't change to the value returned by the formatter. This seems illogical because the formatter of mydir should receive the result of the array-to-string formatter.
angular.module("app", []);
angular.module("app").directive("arrayToString", function() {
return {
restrict: "A",
require: "?ngModel",
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$formatters.push(function(array) {
console.log("formatter called");
var text = "";
angular.forEach(array, function(e) {
text += e.label + ", ";
});
text = text.substring(0, text.length - 2);
console.log(text);
return text;
});
}
};
});
angular.module("app").directive("mydir", function() {
return {
restrict: "E",
scope: {
ngModel: "="
},
require: "?ngModel",
link: function(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$formatters.push(function(alreadyFormattedValue) {
scope.myString = alreadyFormattedValue;
});
},
template: "<div>{{myString}}</div><div>{{ngModel}}</div>"
}
});
angular.module("app").controller("Controller", function() {
var _this = this;
_this.myValues = [
{ label: "apple" },
{ label: "lemon" },
{ label: "pear" }
];
_this.add = function() {
_this.myValues.push({ label: "strawberry" });
}
});
<!DOCTYPE html>
<html>
<head>
<script src="https://code.angularjs.org/1.4.8/angular.js" data-semver="1.4.8" data-require="<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="dcbdb2bba9b0bdaef2b6af9cedf2eff2eeec">[email protected]</a>"></script>
<link href="style.css" rel="stylesheet" />
<script src="script.js"></script>
</head>
<body ng-app="app" ng-controller="Controller as ctrl">
<mydir ng-model="ctrl.myValues" array-to-string=""></mydir>
<button type="button" ng-click="ctrl.add()">Add</button>
</body>
</html>