加载中...

AngularJS之指令中controller与link(十二)


前言

在指令中存在controller和link属性,对这二者心生有点疑问,于是找了资料学习下。

话题

首先我们来看看代码再来分析分析。

第一次尝试

页面:

    <custom-directive></custom-directive>

脚本:

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>{{vm.test}}</div>',
        link: function(){},
        controller: directiveController,
        controllerAs: 'vm'
    };

    return directive;
}

function directiveController() {
    var vm = this;
    vm.test = "I'm from Controller";
}

 

【注】:基础还是非常重要,页面上为custom-directive,在脚本我写成customdirective时死都没出效果,改成customDirective才好使。

第二次尝试

页面自定义指令不变,我们就修改下脚本:

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>{{test}}</div>',
        link: directiveLink
    };

    return directive;
}


function directiveLink(scope,elem,attr) {
    scope.test = "I'm from Link";
}

到这里,我们不仅要开始思索:指令中的controller和link都可以实现同样的效果,那在指令中放这两个属性干嘛?我们的代码到底是放在controller还是link中?

我们首先来看看当二者一起使用时,呈现结果的顺序即在编译前后生成的顺序。

controller和link编译顺序

我们将脚本进行修改如下:

angular
    .module('app',[])
    .directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<div>xpy0928{{test}}</div>',
        link: directiveLink,
        controller:directiveController
    };

    return directive;
}

function directiveController($scope){
    $scope.test = " from contrller cnblogs";
}

function directiveLink(scope,elem,attr) {
    scope.test = scope.test + ",and from link cnblogs";
}

生成如下:

我们由此得出结论:编译之前执行控制器(controller),编译之后执行链接(link)。

但是我们还未从根本上解决问题,在controller和link应该放哪些代码?我们接下来再看一个例子:

var app = angular.module('app',[]);
    
app.directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<child-directive><child-directive>',
        controller: function($scope, $element) {
            $element.find('span').text('hello cnblogs!');
        }
    };

    return directive;
}
app.directive("childDirective",childDirective);

function childDirective() {
    var directive = {
        restrict: 'EA',
        template: '<h1>hello xpy0928</h1>',
        replace: true,
        link: function($scope, $element, attr) {
            
            $element.replaceWith(angular.element('<span>' + $element.text() + '</span>'));
        }
    }
    return directive;
}

此时结果应该还是hello xpy0928还是hello cnblogs呢?我们看下结果:

我们再来将如上进行修改看看:

var app = angular.module('app',[]);
    
app.directive('customDirective', customDirective);

function customDirective() {
    var directive = {
        restrict: 'EA',
        template: '<child-directive><child-directive>',
        link: function(scope, el) {
            el.find('span').text('hello cnblogs!');
        }
    };

    return directive;
}
app.directive("childDirective",childDirective);

function childDirective() {
    var directive = {
        restrict: 'EA',
        template: '<h1>hello xpy0928</h1>',
        replace: true,
        link: function($scope, $element, attr) {
            
            $element.replaceWith(angular.element('<span>' + $element.text() + '</span>'));
        }
    }
    return directive;
}

为什么会出现如此情况?因为在controller函数中此时所有child-directive指令中的link函数还未运行所以此时替换无效。

由此我们可以基本得出在controller和link中应该写什么代码的结论:

(1)在controller写业务逻辑(我们明白业务逻辑大部分是放在服务中),这里所说的业务逻辑乃是为呈现视图之前而准备的数据或者是与其他指令进行数据交互而暴露这个api。

(2)在link中主要操作DOM。

总结

指令乃是AngularJS中比较重要的一块,里面涉及到的东西也是非常之多,时不时的去往里面去灌东西,慢慢就会得心应手。


还没有评论.