指令初始化和加载数据

时间:2016-04-07 13:16:15

标签: javascript angularjs

我对AngularJs中的指令有疑问,因为我似乎并不完全理解它们 那么情况就是下一个:
1)有一个指令:

// directive
function myDir() {
    var directive = {
        restrict: 'A',
        replace: false,
        transclude: false,
        templateUrl: '/js/shared/directives/myDir/myDir.html',
        controller: 'myDirController',
        scope: {
            myDir: '='
        }
    };
    return directive;
}

2)该指令允许执行一些操作:

// directive controller
function myDirController($scope) {
    var something = {};
    var whatevers = [];

    $scope.myDir = {
        createSmth: createSmth,
        setSmthOptions: setSmthOptions,
        addWhatever: addWhatever,
        removeWhatever: removeWhatever
    };

    function createSmth() {
        something = {
            someOption1: someDefaultValue1,
            someOption2: someDefaultValue2,
            someOption3: someDefaultValue3,
        };
    }

    function setSmthOptions(options) {
        angular.extend(something, options);
    }

    function addWhatever(options) {
        var newWhatever = {
            someOption1: someDefaultValue1,
            someOption2: someDefaultValue2,
            anotherOptions: options
        };

        whatevers.push(newWhatever);
    }

    function removeWhatever(whatever) {
        var idx = whatevers.indexOf(whatever);
        whatevers.splice(idx, 1);
    }
}

3)该指令的激活功能是:

activate()
function activate() {
    createSomething();
}

还有一个页面,我正在使用这个指令:

// html
...
<div my-dir="vm.myDir"></div>
...

// controller
...
vm.id = $routeParams.id;
...

activate();
function activate() {
    $q.when(loadData()).then(function() {
        initSomething();
    });
}

function loadData() {
    if (!id) {
        vm.model = {
            data: []
        };
        return null;
    } else {
        // makes request to backend
        myService.getData(id)
            .then(function (data) {
                vm.model = data;
            }).catch(function (error) {
                console.log(error);
            }).finally(function() {
                vm.model = vm.model || {
                    data: []
                };
            });
    }
}

function initSomething() {
    if (vm.myDir) {
        vm.myDir.setSmthOptions(vm.smthOptions);

        vm.whateverOptions.forEach(function (option) {
            vm.myDir.addWhatever(option);
        });
    }
}

问题是指令可以在获取数据后初始化,因为在id = undefined的情况下,我们创建默认模型。对不起,但我不想使用$ timeout,因为我觉得它看起来很难看。

现在我正在使用下一个解决方案:

var watcher = $scope.$watch(
    function () {
        return {
            model: $scope.vm.model,
            myDir: $scope.vm.myDir
        };
    },
    function (newObj) {
        if (newObj.model && newObj.myDir) {
            initSomething();
            watcher();
        }
    },
    true
);

但我不确定使用它是否合适。也许有更好的解决方案。

问题是:我该如何解决这个问题?如何在加载数据和初始化指令后调用函数?

2 个答案:

答案 0 :(得分:0)

$timeout将在下一阶段触发摘要周期,可能是您正在寻找可以使用$scope.$evalAsync()的相关性能。这是一篇关于这个主题的简洁文章。

http://www.bennadel.com/blog/2605-scope-evalasync-vs-timeout-in-angularjs.htm

答案 1 :(得分:0)

您的服务电话是异常的。因此,当loadData函数完成并进行服务调用时,vm.model尚未初始化。您可以将代码更新为以下内容:

&#13;
&#13;
function activate() {
    loadData().then(function() {
        initSomething();
    });
}

function loadData() {
    var deferred = $q.defer();
    if (!id) {
        vm.model = vm.model || {
            data: []
        };
        return $q.resolve();
    } // makes request to backend
    else {
        myService.getData(id)
            .then(function(data) {
                vm.model = data;
            }).catch(function(error) {
                console.log(error);
            }).finally(function() {
                vm.model = vm.model || {
                    data: []
                };
                deferred.resolve();
            });
        return deferred.promise;
    }

}
&#13;
&#13;
&#13;