Почему нельзя использовать асинхронный ответ для генерации шаблона HTML в угловой директиве?

0

Я хочу реализовать подобный виджет для разных типов документов. Я попытался использовать данные области для генерации HTML-кода шаблона, вот что я сделал:

  angular.module('app.common')
    .directive('like',['favoritesResource','session','$q', like]);

  function like(favoritesResource, session, $q, $scope) {

    var news = $q.defer();

    function link(scope, el) {
      //console.log(scope);
      news.resolve(scope.vm.theNews);
    };

    function getTemplate(el, attrs) {
      loadNews().then(function(news) {
        console.log(news);
        favoritesResource.isLike(session.getCurrentUser.id, {docType: news.type, docId: news.id}, function(status) {
          if (status == 'like'){
            return '<button class="fa fa-heart" ng-click="vm.likeIt()">like</button>';
          }else {
            return '<button class="fa fa-heart-o" ng-click="vm.likeIt()">like</button>'
          }
        });
      });
    };

    function loadNews() {
      return news.promise;
    }

    return {
      link: link,
      restrict: 'E',
      template: getTemplate(),
      replace: true
    };
  }

Я обнаружил, что объект "новости" может быть напечатан в консоли, но результат html <like></like>, а не <button class="fa fa-heart" ng-click="vm.likeIt()">unlike</button> или <button class="fa fa-heart-o" ng-click="vm.likeIt()">like</button>, может ли кто-нибудь сказать мне, что случилось? Или у вас есть предложение написать такой виджет?

ОБНОВЛЕНИЕ:

Этот виджет находится в контроллере, используемом для отображения содержимого документа, вот мой контроллер:

  angular
    .module('app.news')
    .controller('ReadNewsController', ReadNewsController);

  ReadNewsController.$inject = ['theNews', '$scope', 'favoritesResource', 'session'];
  function ReadNewsController(theNews, $scope, favoritesResource, session) {
    var vm = this;
    vm.theNews = theNews;

    vm.likeIt = function() {
      favoritesResource.like(session.getCurrentUser.id, {docType:theNews.type, docId: theNews.id});
    };

    vm.unlikeIt = function() {
      favoritesResource.disLike(session.getCurrentUser.id, {docType:theNews.type, docId: theNews.id});
    };

    vm.isLikeIt = function() {
      favoritesResource.isLike(session.getCurrentUser.id, {docType:theNews.type, docId: theNews.id});
    };
  }

и маршруты:

var module = angular.module('app.news', ['ui.router', 'app.common', 'app.data']);

  module.config(appConfig);

  appConfig.$inject = ['$stateProvider'];

  function appConfig($stateProvider) {.state('app.readNews', {
        url: '/news/read/:id',
        templateUrl: 'app/modules/news/read/news.html',
        controller: 'ReadNewsController as vm',
        resolve: {
          theNews: function(newsResource, $stateParams) {
            return newsResource.get({id: $stateParams.id}).$promise.then(function(item){
              item.type = 'news'; //for 'like' directive
              return item;
            })
          }
        }
      })
  • 0
    Метод getTemplate() возвращает значение до того, как функция в функции then() будет выполнена, поскольку она асинхронна.
  • 0
    единственное отличие, которое я вижу, в классе ... вы должны использовать значение ng-класса .. он может изменить его динамически в зависимости от ответа .then
Теги:
directive

1 ответ

1
Лучший ответ

Гораздо проще добавить условную логику к шаблону с помощью ng-class. Затем загрузите данные и установите переменную isLiked

function like() {

    return {
      link: link,
      restrict: 'E',
      template: '<button class="fa" ng-class="{\'fa-heart\': isLiked,\'fa-heart-o\': !isLiked }" ng-click="vm.likeIt()">like</button>',
      replace: true
    };
  }

 function link(scope, el) {
  loadNews().then(function(news) {

    favoritesResource.isLike(session.getCurrentUser.id, {docType: news.type, docId: news.id}, function(status) {
        scope.isLiked = status === 'like'
    });
  });
};
  • 0
    он не должен работать, потому что isLiked не существует при использовании «шаблона».
  • 0
    это не имеет смысла ... вы будете использовать тот же вызов API, который вы использовали, чтобы проверить, какой шаблон, и вы всегда можете установить значение по умолчанию false
Показать ещё 4 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню