最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Is safeApply is best practice? - Stack Overflow

programmeradmin0浏览0评论

I'm trying to work more with directives to apply a bit more best practices but I have some questions on the best way to apply a scope value from a directive.

In this fiddle demo, you can see if you click on the "Toggle displayMenu " button, the div is still toggled on. If you toggle lines 7-8 in directive's code :

scope.yolo = function () {
    scope.ctrl.toggle(); // COMMENT ME
    //scope.ctrl.toggleApply(); // UNCOMMENT ME
};

to :

scope.yolo = function () {
    //scope.ctrl.toggle(); // COMMENT ME
    scope.ctrl.toggleApply(); // UNCOMMENT ME
};

the displayMenu div will toggle off.

Now, the problem is I am forced to write 2 functions, one with "$scope.$apply" and one without, and it is clearly not a smart way to do it... unless I use safeApply like :

 $rootScope.safeApply = function(fn) {
        var phase = this.$root.$$phase;
        if(phase == '$apply' || phase == '$digest') {
            if(fn && (typeof(fn) === 'function')) {
                fn();
            }
        } else {
            this.$apply(fn);
        }
    };

Is the safeApply is the best practice ? If not, what is the best way to acplish what I want ?

I'm trying to work more with directives to apply a bit more best practices but I have some questions on the best way to apply a scope value from a directive.

In this fiddle demo, you can see if you click on the "Toggle displayMenu " button, the div is still toggled on. If you toggle lines 7-8 in directive's code :

scope.yolo = function () {
    scope.ctrl.toggle(); // COMMENT ME
    //scope.ctrl.toggleApply(); // UNCOMMENT ME
};

to :

scope.yolo = function () {
    //scope.ctrl.toggle(); // COMMENT ME
    scope.ctrl.toggleApply(); // UNCOMMENT ME
};

the displayMenu div will toggle off.

Now, the problem is I am forced to write 2 functions, one with "$scope.$apply" and one without, and it is clearly not a smart way to do it... unless I use safeApply like :

 $rootScope.safeApply = function(fn) {
        var phase = this.$root.$$phase;
        if(phase == '$apply' || phase == '$digest') {
            if(fn && (typeof(fn) === 'function')) {
                fn();
            }
        } else {
            this.$apply(fn);
        }
    };

Is the safeApply is the best practice ? If not, what is the best way to acplish what I want ?

Share Improve this question asked Mar 11, 2016 at 0:02 Jacques CornatJacques Cornat 1,6521 gold badge20 silver badges35 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 8

Looking at the $$phase is considered bad practice. From a similar topic the angular devs have said that:

For future-proofing reasons, you should not use $$phase

The remended best practice is to either use $timeout or $evalAsync which both defer the execution of the code. In essence, both functions will be executed in a new $digest cycle so you don't have to manually call $apply yourself. Most of the time you can probably use $evalAsync if you just need to update some code in a safeApply scenario.

scope.$evalAsync(function(scope) {
  // run the toggle function without caring if you're in the digest or not
  scope.ctrl.toggle();
});

You can read this article by Ben Nadal to see how the different functions get executed in the JavaScript process.

发布评论

评论列表(0)

  1. 暂无评论