【问题标题】:Controller function executes as callback控制器函数作为回调执行
【发布时间】:2014-10-22 06:22:24
【问题描述】:

我将 html 的部分 (div) 更改为指令,在更改之前,我的 html 如下所示:

<div ng-controller="SearchCtrl as search">
    <div id="firstDirective">
        .
        .
        .
    <div>
    <div id="secondDirective">
        .
        .
        .
    <div>
</div>

与关联的控制器一起工作正常。我打算把 html 改成这样:

<div ng-controller="SearchCtrl as search">
    <first-directive>
    <second-directive>
</div>

相应的angular.directive 定义具有独立的作用域(return {..., scope: {attr: '=attr', func: '&amp;func'},...}),并且属性和函数是从控制器传递的。 将第一个 div 更改为指令 (first-directive) 后,它仍然运行良好。但是,在创建 second-directive 并替换相应的 div 之后,该部分不再起作用(第一个部分仍然有效)。这是我的控制器:

app.controller('SearchCtrl', ['$scope', '$http', function($scope, $http){

    var self = this;

    self.data = {};

    self.clickSearch = function() {

        self.retrieve(param1, param2);
        .
        .
        .
        console.log('clickSearch log, data: ', self.data);
    }

    // retrieve is reused, called directly in some parts of html, 
    // thus I attached it as a controller function
    self.retrieve = function(param1, param2) {

        // some $http.get and assign to data
        .
        .
        .

        console.log('retrieve log, data:', self.data);
    }
    // some other functions, some are passed to the directives
    .
    .
    .
});

但是日志显示:

[LOG]clickSearch log, data: {}
[LOG]retrieve log, data: {...//some assigned values}

看起来 clickSearch 函数先完成,然后 retrieve 函数稍后执行,因此我得到空数据。我的背景来自 Java,所以我不完全理解 JavaScript 中回调的概念,我怀疑这就是这里发生的事情。我该如何补救?谢谢。

【问题讨论】:

  • 从你的代码看起来,任何对clickSearch 的调用都会触发一个“retrieve”日志,然后是一个“clickSearch”日志,因为它们是同步发生的。但是,如果其中一个语句嵌套在您传递给指令的另一个函数(回调)中,情况就不同了。
  • 顺便说一句,这可能是因为您的 Java 背景,但这里几乎没有任何理由将dataclickSearchretrieve 声明为this 的成员。只需声明局部变量,使用和推理会更简单。 (在 Java 中不这样做的原因是缺乏对词法闭包的支持)。
  • @ValentinWaeselynck “局部变量”是什么意思? “本地”是哪个?控制器内部?可能无法将它们设为本地,因为我需要将这些数据和方法公开为控制器属性,以便我可以在 html 部分中调用它们。
  • 我的意思是var data = {};。将它们暴露给 HTML 包括使它们成为 $scope 对象的属性,而不是您的控制器对象。

标签: javascript angularjs


【解决方案1】:

试试这个

app.controller('SearchCtrl', ['$scope', '$http', function($scope, $http){

var self = this;

self.data = {};

self.clickSearch = function() {

    self.retrieve(param1, param2, function(data){
       .
       .
       .
        console.log('clickSearch log, data: ', data);
        console.log('clickSearch log, data: ', self.data);
    });
}

// retrieve is reused, called directly in some parts of html, 
// thus I attached it as a controller function
self.retrieve = function(param1, param2, callback) {

    // some $http.get and assign to data
    .
    .
    .

    console.log('retrieve log, data:', self.data);
    callback(data);//$http.get{url:url,success:callback}
}
// some other functions, some are passed to the directives
.
.
.

});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    相关资源
    最近更新 更多