1

角度新手问题:

我有一个简单的 AngularJS 测试应用程序,它显示了控制器和指令如何协同工作。控制器设置一些硬编码值aBaC范围,然后指令在 HTML 中显示这些值。有用。这是JSFiddle。代码如下。当你运行它时,你可以看到控制台输出如预期的那样:

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

我所做的唯一更改(在这个新的JSFiddle中看到)是在控制器的myFunc函数中:我用以下内容替换了硬编码的值:

  response = $http.post('http://jsonplaceholder.typicode.com/posts',
    {
      'XXXXX': 'YYYYYYY'
    }
  )    
  self.scopeAB = response.id;
  self.scopeAC = response.id;

我已经通过测试 API 的响应curl,它工作正常。那么,为什么该指令将aB和的值报告aCundefined?我该如何解决这个问题?我可以说它与 HTTP 调用的异步特性有关。但我不知道如何使它正常工作。

HTML:

<body ng-app="myApp">
  <div ng-controller="MyCtrl as ctrl">
    <div ng-view></div>
    <ul>
      <li>{{1+1}}</li>
      <li><my-directive a-b="null" a-c="'Goodbye'"></my-directive></li>
      <li><my-directive a-b="ctrl.scopeAB" a-c="ctrl.scopeAC"></my-directive></li>
      ab = {{ctrl.scopeAB}}, ac = {{ctrl.scopeAC}}
    </ul>
  </div>
</body>

工作的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';
    }();
  }
);

更新: 克莱斯建议我使用这个JSFiddle。但这对我不起作用,因为我绝对需要在指令的控制器中访问aBaC我需要根据它们的值来改变模板。这个 JS Fiddle 似乎向他们展示了在那里总是未定义的。

4

2 回答 2

2

您应该阅读有关$http 服务的文档。调用是异步的,你在then回调中处理成功的响应

$http.post('http://jsonplaceholder.typicode.com/posts', {'XXXXX': 'YYYYYYY'})
   .then(function(response) {
      self.scopeAB = response.data.id;
      self.scopeAC = response.data.id;
   })
于 2016-01-16T06:28:17.663 回答
1

Claies 建议我使用这个 JSFiddle。但这对我不起作用,因为我绝对需要在指令的控制器中访问 aB 和 aC 的值。我需要根据它们的值来改变模板。这个 JS Fiddle 似乎向他们展示了在那里总是未定义的。

如果您使用@Claies方法,则需要在请求解决$watch时触发的对象上放置一个。$http

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);

});

JSFiddle 上的演示。

坦率地说,我认为你最好听从@jumbopap的建议。使用 httpPromise 和.then方法并从onFulfilled函数中检索数据。

于 2016-01-16T08:40:39.040 回答