2017-07-16 93 views
2

所以我有一個是應該執行的jQuery插件的功能很簡單的指令:指令沒有加載範圍變量

angular.module('myproject.directives').directive('starRating', function() { 
    return { 
     restrict: 'A', 
     scope: { 
      rating: '=' 
     }, 
     link: function (scope, elem, attr) { 
      console.log('rating', scope.rating); 

      elem.barrating({ 
       theme: 'css-stars', 
       readonly: true 
      }); 

      elem.barrating('set', scope.rating); 
     } 
    }; 
}); 

下面是HTML:

<select class="service-rating" 
     ng-show="!!currentJob.Review.ServiceRating" 
     star-rating rating="currentJob.Review.ServiceRating"> 
    <option value="1">1</option> 
    <option value="2">2</option> 
    <option value="3">3</option> 
    <option value="4">4</option> 
    <option value="5">5</option> 
</select> 

的「currentJob」變量只在$ http調用後設置,但是隻有當div被填充後纔會顯示div。日誌爲scope.rating返回'null',但是如果我自己記錄'scope',它就會清楚地顯示按照預期填充的'rating'屬性。

此外,如果我只是輸入一個硬編碼的數字'評級'屬性該指令按預期工作。

我不確定我要去哪裏錯了?有任何想法嗎?

回答

2

本質的問題是,當你正在使用ng-show,你的指令被從Ajax檢索您的star值之前加載到DOM樹,它處理和barrating被連接到DOM與star價值0。基本上ng-show所做的只是在HTML上隱藏或顯示DOM,只需在DOM上切換display css屬性即可。

所以你可以有兩個選項讓你的星形組件工作。

  1. 使用ng-if而不是ng-show
  2. 使用$watch一個組件內更新star等級(這將是很好的解決方案去)。

    link: function (scope, elem, attr) { 
        console.log('rating', scope.rating); 
    
        elem.barrating({ 
         theme: 'css-stars', 
         readonly: true 
        }); 
        scope.$watch('star', function(newValue){ 
         elem.barrating('set', newValue); 
        }); 
    } 
    
  3. 您可以將兩者結合使用。只有當您使用ng-if &進行評分時才顯示評分,那麼評分的任何變化將由$watch進行處理以更新barrating元素。
+1

非常感謝 - 非常感謝爲什麼它不工作的解釋! – alimac83

1

更改指令作出反應,在評級調整:

app.directive('starRating', function() { 
    return { 
     restrict: 'A', 
     scope: false, 
     link: function (scope, elem, attr) { 

      elem.barrating({ 
       theme: 'css-stars', 
       readonly: true 
      }); 

      scope.$watch(attr.rating, function (newValue) { 
       elem.barrating('set', newValue); 
       console.log('rating', newValue); 
      }); 

     } 
    }; 
}); 

編碼這種方式,在每一個消化週期觀察者檢查更改由rating屬性定義的角度表達,並更新適當地插入barrating插件。


更新

我沒想到用的手錶,但我很好奇,爲什麼我的原始設置沒有工作。

原始設置不起作用,因爲它僅在指令初始化時設置星級評定一次。由於數據在指令初始化後從服務器到達,插件不會看到新數據。通過使用手錶,每當控制器更改變量時(包括從服務器到達值的時間),設置都會更新。

另請注意,另一個答案hardwires手錶特定範圍變量(不明智)。使用屬性來聲明特定的作用域變量是明智的。它使得一個更通用的指令。

當一個指令缺少一個使用AngularJS綁定的模板時,更爲明智,避免了隔離範圍。將手錶直接放在屬性上,如本例所示。

+0

謝謝。我確實想過使用手錶,但我很好奇,爲什麼我的原始設置不起作用。我只是因爲完整的解釋纔將答案標記爲解決方案 – alimac83