Model inside a template of a custom directive never updated

I have a simple custom directive myElement with a templateUrl that print a simple message:

<p>Message: {{message}}</p>

Here's the definition of my directive:

testapp.directive('myElement', function() {
    return {
        restrict: 'E',
        template: '<p>Message: {{message}}</p>',
        link: function(scope, elem, attrs) {
            scope.message = 'This message is never updated... :(';
            setTimeout(function() {
                scope.message = "Why this message is never shown?";
            }, 1000);
        }
    };
});

After 1 second, I expect an update of the message to "Why this message is never shown?". Unfortunately, the message is never updated.

Here is the jsFiddle: http://jsfiddle.net/seyz/SNMfc

Could you explain me why?

Due to how Angular dirty checking works, when you execute code outside of angular scope (e.g. using setTimeout, setInterval, or from within some third-party plugin callback) the changes produced by that code invocation won't be 'recognized' immediately by Angular scope.

For such scenarios you need to wrap your code inside the scope.$apply() method.

In this particular case you may simply use $timeout function to replace your setTimeout(fn, 1000)call with $timeout(fn, 1000)and your code will be wrapped with scope.$apply() call (Plunker).

You will need to use scope.$apply();

setTimeout(function() {
    scope.message = "Why this message is never shown?";
    scope.$apply();
}, 1000);

From the documentation:

$apply() is used to execute an expression in angular from outside of the angular framework. (For example from browser DOM events, setTimeout, XHR or third party libraries).