AngularJS - scope.$watch vs. ctrl.$render

by Norlihazmey Ghazali

HTML

<div ng-app="form-example2">
    <div ng-controller="MyCtrl">
        <div contentEditable="true" ng-model="content" title="Click to edit">Some</div> <pre>model = {{content}}</pre>
        <a href="" ng-click="changeModel()">change model</a>
    </div>
    <style type="text/css">
        div[contentEditable] {
            cursor: pointer;
            background-color: #D0D0D0;
        }
    </style>
</div>

CSS

</style> <!-- Ugly Hack due to jsFiddle issue: http://goo.gl/BUfGZ --> <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.5/angular.min.js"></script> <style> ​.ng-invalid {
    border: 1px solid red;
}
​

JavaScript

// http://stackoverflow.com/questions/15393427/angularjs-directives-best-practices-when-using-ngmodel-with-jquery-widget

function MyCtrl($scope) {
    $scope.changeModel = function () {
        $scope.content = "reset text"
    }
}
angular.module('form-example2', []).directive('contenteditable', function () {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {
            // view -> model
            elm.bind('blur', function () {
                scope.$apply(function () {
                    ctrl.$setViewValue(elm.html());
                });
            });
            scope.$watch(attrs.ngModel, function() {
                console.log('watch called')
            });
            // model -> view
            ctrl.$render = function () {
                console.log('render called')
                elm.html(ctrl.$viewValue);
            };

            // load init value from DOM
            ctrl.$setViewValue(elm.html());
        }
    };
});