Javascript 为什么AngularJS指令使用硬编码值,但使用http请求/响应失败?

Javascript 为什么AngularJS指令使用硬编码值,但使用http请求/响应失败?,javascript,angularjs,angular-promise,angular-directive,angular-controller,Javascript,Angularjs,Angular Promise,Angular Directive,Angular Controller,有棱角的新手问题: 我有一个简单的AngularJS测试应用程序,它展示了控制器和指令如何协同工作。控制器在作用域上设置一些硬编码值aB和aC,然后指令以HTML显示这些值。它起作用了。这是你的电话号码。代码如下。运行它时,您可以看到控制台输出与预期一致: JS line #63: this.aB = null JS line #64: this.aC = Goodbye JS line #63: this.aB = Hello JS line #63: this.aC = World

有棱角的新手问题:

我有一个简单的AngularJS测试应用程序,它展示了控制器和指令如何协同工作。控制器在作用域上设置一些硬编码值
aB
aC
,然后指令以HTML显示这些值。它起作用了。这是你的电话号码。代码如下。运行它时,您可以看到控制台输出与预期一致:

JS line #63: this.aB =  null
JS line #64: this.aC =  Goodbye
JS line #63: this.aB =  Hello
JS line #63: this.aC =  World
但是,当我将硬编码值更改为从测试API检索的值时,它失败了。控制台输出如下所示:

JS line #63: this.aB =  null
JS line #64: this.aC =  Goodbye
JS line #63: this.aB =  undefined
JS line #63: this.aC =  undefined
我所做的唯一更改(见本新文档)是控制器的
myFunc
函数:我用以下内容替换了硬编码值:

  response = $http.post('http://jsonplaceholder.typicode.com/posts',
    {
      'XXXXX': 'YYYYYYY'
    }
  )    
  self.scopeAB = response.id;
  self.scopeAC = response.id;
我已经通过
curl
测试了API的响应,它运行良好。那么,为什么指令将
aB
aC
的值报告为
undefined
?我如何解决这个问题?我可以看出这与HTTP调用的异步性质有关。但我不知道如何使它正确工作

HTML:


  • {{1+1}}
  • ab={{ctrl.scopeAB},ac={{ctrl.scopeAC}
工作Javascript:

myApp = angular.module('myApp',[]);
myApp.directive('myDirective',function(){
    return {
      restrict:'E',
      scope: {
        aB: '=',
        aC: '='
      },
      controller: 'DirectiveCtrl',
      controllerAs: 'dirCtrl',
      bindToController: true,
      template: 'aB={{dirCtrl.aB}} aC={{dirCtrl.aC}} <input ng-model="dirCtrl.aB" />'
    };
  }
);

myApp.controller('DirectiveCtrl', function(){
    var self = this;
    console.log('this.aB = ', self.aB);
    console.log('this.aC = ', self.aC);
})

myApp.controller('MyCtrl', function() {
    var self = this;
    self.myFunc = function() {
      self.scopeAB = 'Hello';
      self.scopeAC = 'World';
    }();
  }
);
myApp=angular.module('myApp',[]);
myApp.directive('myDirective',function(){
返回{
限制:'E',
范围:{
aB:“=”,
aC:“=”
},
控制器:“DirectiveCtrl”,
controllerAs:'dirCtrl',
bindToController:对,
模板:“aB={{dirCtrl.aB}}aC={{{dirCtrl.aC}”
};
}
);
myApp.controller('DirectiveCtrl',function(){
var self=这个;
log('this.aB=',self.aB);
log('this.aC=',self.aC);
})
myApp.controller('MyCtrl',function(){
var self=这个;
self.myFunc=函数(){
self.scopeAB='Hello';
self.scopeAC='World';
}();
}
);
更新:
克莱斯建议我用这个。但它对我不起作用,因为我绝对需要
aB
aC
的值才能在指令的控制器中访问。我需要根据它们的值更改模板。这个JS提琴似乎显示它们总是未定义的。

您应该阅读页面上的文档。调用是异步的,您可以在
然后
回调中处理成功的响应

$http.post('http://jsonplaceholder.typicode.com/posts', {'XXXXX': 'YYYYYYY'})
   .then(function(response) {
      self.scopeAB = response.data.id;
      self.scopeAC = response.data.id;
   })
Claies建议我使用这个JSFIDLE。但它对我来说不起作用,因为我绝对需要在指令的控制器中访问aB和aC的值。我需要根据它们的值更改模板。这个JS提琴似乎显示了它们始终未定义

如果使用@Claies方法,则需要在
$http
请求解析时激发的对象上放置
$watch

myApp.controller('DirectiveCtrl', function($scope){
    var self = this;
    $scope.$watch(function() {return self.scopeObject}, function (objVal) {
        console.log("watch fired");
        console.log('objVal.aB = ', objVal.aB);
        console.log('objVal.aC = ', objVal.aC);    
    },true);

});
这个


坦白地说,我认为你最好还是听从Jumbopp的建议。使用httpPromise和
。然后
方法,从
onCompleted
函数中检索数据。

产生相同的控制台输出:答案基本正确,但使用
。然后
时,响应略有不同。我更新了答案,
response.data.id
将是正确的用法。但是,这仍然没有100%的意义,因为此代码实际上会使
scopeAB
scopeAC
等于相同的值,这相当奇怪。请查看控制台上的说明:
混合内容:位于https://fiddle.jshell.net/saqibali75/8maswfqb/1/show/'已通过HTTPS加载,但请求了一个不安全的XMLHttpRequest端点'http://jsonplaceholder.typicode.com/posts'. 此请求已被阻止;内容必须通过HTTPS提供。
加载不带HTTPS的页面。Claies:即使在编辑之后,控制台输出仍然保持不变:(是的,我知道scopeAB和scopeAC是相同的。这只是为了测试目的。在我的实际应用程序中,它们将不同)就像我说的,加载不带https的页面并检查输出。这里的问题是另一个需要解释的角度。如果你想讨论正在发生的事情和可能的处理方法,我已经跳回AngularJS聊天频道。这里的答案确实回答了为什么控制器值没有用
$http
更新的问题,但这不是全部。至于为什么控制器更新时指令没有更新,这是另一个话题,我觉得我在前面的问题中讨论这个话题时可能部分误导了你。我根据我们最近的聊天对话更新了这个问题。但问题仍然存在。@jumbopp在这个答案中被提到。@claies在这个答案中被提到。georgeawg我想用@jumbopp的答案,但我不完全理解,因为他没有展示出一点点它完全有效。
myApp.controller('DirectiveCtrl', function($scope){
    var self = this;
    $scope.$watch(function() {return self.scopeObject}, function (objVal) {
        console.log("watch fired");
        console.log('objVal.aB = ', objVal.aB);
        console.log('objVal.aC = ', objVal.aC);    
    },true);

});