动态$scope DOM元素还没有准备好进行插件初始化

时间:2022-11-28 16:28:23

Quite new to the world of AngularJS and barring a few tutorials and demos I've picked through, this is my first attempt at building something in depth. So apologies if I don't properly explain what's likely a simple question!

对AngularJS来说,这是一个全新的世界,除了我挑选的一些教程和演示,这是我第一次尝试深入地构建一些东西。如果我不能很好地解释一个简单的问题,我很抱歉!

I have a controller that looks like:

我有一个控制器

myApp.controller('ShowCtrl', function($scope, $routeParams, $http) {
   $http({
      method: 'GET',
      url: 'rest/details/'+ $routeParams.identifier
   }).then(function successCallback(response) {
      $scope.shows = response.data;
      myPlugin.init();

   }, function errorCallback(response) {
      $scope.shows = "something bad happened";
   });
});

This makes a GET request to a custom REST interface which makes a call to an external/3rd party api. I then take that api response, assign it to the scope, and loop through it to display the items in my partial .html

这将向自定义REST接口发出GET请求,该接口调用外部/第三方api。然后,我获取该api响应,将其分配到范围,并对其进行循环,以在我的部分.html中显示项目

<li ng-repeat="(key, show) in shows" class="required-element">
  {{ show.title }}
</li>

This works GREAT. The scope has the response and I can loop and display the elements as expected.

这是伟大的。作用域具有响应,我可以按预期循环和显示元素。

The issue arises with the fact that I'm also using a plugin which seems to get initialized before the elements are written to the DOM.

问题在于,我还使用了一个插件,它似乎在元素被写入DOM之前被初始化。

You can see in the code above that the plugin's .init(); is called just after assigning the api response to the controller $scope. Therefore, no functionality from the plugin is bound to those elements.

您可以在上面的代码中看到插件的.init();在将api响应分配给controller $scope之后调用。因此,插件中的任何功能都不会绑定到这些元素。

Is there some way to defer my init(); to a time when I can be sure the DOM elements have been written to the page? I've done a bunch of searching around for a solution and it seems like maybe an angular directive might be a solution here?

是否有什么方法可以延迟init();到我可以确定DOM元素已经被写入页面的时候?我已经做了大量的研究来寻找一个解似乎一个角方向可能是一个解?

Any help is greatly appreciated!

非常感谢您的帮助!

[UPDATE] - OK, I've found a couple of solutions so far (one of which is causing me to facepalm). Neither seems like the "best" way though. failed a couple of times

[更新]-好的,到目前为止我已经找到了几个解决方案(其中一个方案让我接受了facepalm)。但这两种方式似乎都不是最好的。失败了几次

- the easy way. init the plugin via jQuery document.ready(); - this works for some reason and makes me feel silly for how long it took me to try. (nvm, didn't work)

——简单的方法。通过jQuery document.ready()来初始化插件;-这是有原因的,让我觉得我花了很长时间去尝试。(nvm不工作)

- by moving my $http GET requests to an angular "Factory" with a promise to return. I would load the scope with one, then my plugin with another. Seems like overkill but quite the learning experience.

-将我的$http GET请求移动到一个有棱角的“工厂”,并承诺返回。我将用一个加载范围,然后用另一个插件加载插件。这似乎有点过头了,但确实是一次学习的经历。

1 个解决方案

#1


2  

You need to inject $timeout to your controller and use it like this:

你需要向你的控制器注入$timeout值,并像这样使用:

myApp.controller('ShowCtrl', function($scope, $routeParams, $http, $timeout) {
   $http({
      method: 'GET',
      url: 'rest/details/'+ $routeParams.identifier
   }).then(function successCallback(response) {
      $scope.shows = response.data;
      $timeout(function() {
           myPlugin.init();
      });
   }, function errorCallback(response) {
      $scope.shows = "something bad happened";
   });
});

This way you will call the myPlugin.init(); function only after the digest loop has ended and the view is rendered.

这样,您将调用myPlugin.init();只在摘要循环结束并呈现视图之后才执行。

#1


2  

You need to inject $timeout to your controller and use it like this:

你需要向你的控制器注入$timeout值,并像这样使用:

myApp.controller('ShowCtrl', function($scope, $routeParams, $http, $timeout) {
   $http({
      method: 'GET',
      url: 'rest/details/'+ $routeParams.identifier
   }).then(function successCallback(response) {
      $scope.shows = response.data;
      $timeout(function() {
           myPlugin.init();
      });
   }, function errorCallback(response) {
      $scope.shows = "something bad happened";
   });
});

This way you will call the myPlugin.init(); function only after the digest loop has ended and the view is rendered.

这样,您将调用myPlugin.init();只在摘要循环结束并呈现视图之后才执行。