文件中的 $templateCache 未定义?什么时候可以被其他js代码访问? (使用 np 自动完成)

$templateCache from file undefined? When is the accessible by other js code? (with np-autocomplete)

我是 angular 的新手,我正在尝试将 np-autocomplete 集成到我的应用程序中 (https://github.com/ng-pros/np-autocomplete)。但是,当我将 html 字符串作为 $scope.options 中的模板传递时,我只能让它工作,而当我想从单独的 [=30= 加载它时,它不起作用].

我的应用代码如下所示:

var eventsApp = angular.module('eventsApp',['ng-pros.directive.autocomplete'])

eventsApp.run(function($templateCache, $http) {
    $http.get('test.html', {
      cache: $templateCache
    });
   console.log($templateCache.get('test.html'))  // --> returns undefined

   setTimeout(function() {
       console.log($templateCache.get('test.html'))  // --> works fine
   }, 1000);

   //$templateCache.put('test.html', 'html string') //Would solve my issue in the controller,
   //but I would rather prefer to load it from a separate html as I'm trying above

在我的控制器中,我设置自动完成选项如下:

controllers.createNewEventController = function ($scope) {
    $scope.options = {
        url: 'https://api.github.com/search/repositories',
        delay: 300,
        dataHolder: 'items',
        searchParam: 'q',
        itemTemplateUrl: 'test.html',  // <-- Does not work  
    };
    //other stuff...
}

然而,似乎 test.html 在 np-autocomplete 想要使用它时未定义(因为它也在上面的第一个 console.log 中)。

所以我的直觉告诉我,test.html 可能在 eventsApp.run(...) 加载之前在控制器中被访问。但是我不确定如何解决这个问题?

非常感谢任何帮助。

您的假设很可能是正确的。

$http 的调用是异步的,但是 运行 块不会等待它完成。它将继续执行并且执行将在模板被检索和缓存之前命中控制器等。

一个解决方案是首先检索您需要的所有模板,然后手动 bootstrap 您的应用程序。

另一种可行的方法是推迟 np-autocomplete 指令的执行,直到检索到模板。

为了防止 np-autocomplete 过早地 运行 宁你可以使用 ng-if:

<div np-autocomplete="options" ng-if="viewModel.isReady"></div>

检索到模板后,您可以触发一个事件:

$http.get('test.html', {
  cache: $templateCache
}).success(function() {
  $rootScope.$broadcast('templateIsReady');
});

在你的控制器中监听事件并做出反应:

$scope.$on('templateIsReady', function () {

  $scope.viewModel.isReady = true;
});

如果您愿意,可以立即停止收听,因为事件无论如何都应该只触发一次:

var stopListening = $scope.$on('templateIsReady', function() {

  $scope.viewModel.isReady = true;
  stopListening();
});