angular / router

The Angular 1 Component Router
MIT License
665 stars 135 forks source link

Re-activate hook #405

Open zagros opened 8 years ago

zagros commented 8 years ago

Hi,

I had to change the router.es5.js lines # 170 (belonging to router.registerViewport()) as follows in order to allow for _reactivation__ hook.

This will make the ngNewRouter not refresh a `ng-viewport' on route change if its corresponding canReactivate() method of the related controller returns true.

(In other words, that is if a this.canReactivate() is available on a controller, that controller will not be refreshed if the method returns true. Unlike the "deactivate", the viewports will continue to update even if a particular canReactivate of a given controller/viewport returns false therefore not halting a complete change in $$location state.

This way if I have X viewports, I can optionally choose what viewports to update or not update when a route changes.

I'm sure there will be people saying "but you're not doing it like it's meant to be" but in real world, we need this hook for a complex domain application, and more importantly to keep the consumers & business happy.

It'll be great to have this feature included for the legacy distribution:

router.registerViewport({
            canDeactivate: function(instruction) {
                if (currentController && currentController.canDeactivate) {
                    return invoke(currentController.canDeactivate, currentController, instruction);
                }
                return true;
            },
            activate: function(instruction) {    

                var nextInstruction = serializeInstruction(instruction);
                if (nextInstruction === previousInstruction) {
                    return;
                }    

                instruction.locals.$scope = newScope = scope.$new();
                myCtrl.$$router = instruction.router;
                myCtrl.$$template = instruction.template;
                var componentName = instruction.component;    

                var canReactivatePromiseOrNote = false;
                if (currentController &&
                    currentController.canReactivate)
                    canReactivatePromiseOrNote = currentController.canReactivate();    

                var defer = $q.defer();    

                $q.when(canReactivatePromiseOrNote).then(function(canReactivate) {    

                    var clone = $transclude(newScope, function(clone) {
                        if (canReactivate) {
                            return;
                        }
                        $animate.enter(clone, null, currentElement || $element);
                        cleanupLastView();
                    });    

                    var newController = canReactivate ? currentController : instruction.controller;
                    newScope[componentName] = newController;    

                    var result;
                    if (!canReactivate  &&
                        currentController && currentController.deactivate) {
                        result = $q.when(invoke(currentController.deactivate, currentController, instruction));
                    }    

                    if (!canReactivate) {
                        currentElement = clone;
                        currentScope = newScope;
                        currentController = newController;
                    }    

                    previousInstruction = nextInstruction;    

                    // finally, run the hook
                    if (newController.activate && !canReactivate) {
                        var activationResult = $q.when(invoke(newController.activate,
                            newController, instruction));
                        // debugger;
                        if (result) {
                            defer.resolve(result.then(activationResult));
                        } else {
                            // return activationResult;
                            defer.resolve($q.when(activationResult));
                        }
                    } else if (!result && canReactivate) {
                        //currentController.reactivate();
                        defer.resolve(canReactivate);
                    } else defer.resolve(true);    

                });    

                return defer.promise;
            }
        }, viewportName);