2015-10-04 82 views
1

根據回答here,我一直試圖在一個角度指令中包裝一個jQuery插件(addtocalendar)。我使用的是ui-router,之前的插件可以工作,但是如果我從這個孩子導航到另一個狀態,addtocalendar按鈕將完全消失。在AngularJS指令中包裝jQuery插件

現在,當插件包裹在一個指令中,如果我導航到不同的子狀態然後回來,我能夠看到按鈕,但是,我從指定的插件中得到一個錯誤失效日期。看來,我從Angular提供插件的數據只運行一次,然後再也不會再次提供給插件。

是否有解決方法?

這裏是我的HTML:

 // works fine on first page load 

     <div addtocalendartest> // angular directive 
     <div class="addtocalendar"> //jQuery plugin 
     <div class="arrow-up"></div> 
      <var class="atc_event"> 
      <var bind-once class="atc_date_start">{{event.startDate | date:'yyyy-MM-dd HH:mm:ss'}}</var> 
      <var bind-once class="atc_date_end">{{event.endDate | date:'yyyy-MM-dd HH:mm:ss'}}</var> 
      <var bind-once class="atc_timezone">America/New_York</var> 
      <var bind-once class="atc_title">{{event.description}}</var> 
      <var bind-once class="atc_description">{{event.Synopsis | characters: 200 :false }}</var> 
      <var bind-once class="atc_location">_</var> 
      </var> 
     </div> 
     </div> 

這裏是我創建了一個包含插件邏輯指令:

'use strict'; 

angular.module('myApp') 
.directive('addtocalendartest', function() { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 

    //run jQuery scripts 

      var w = window; 
      var d = document;   
       (function(w, d) { 
        var atc_url = "//addtocalendar.com/atc/", 
         atc_version = "1.5", 
         b = d.documentElement; 
        if (!Array.indexOf) { 
         Array.prototype.indexOf = function(e) { 
          for (var t = 0, n = this.length; t < n; t++) { 
           if (this[t] == e) { 
            return t 
           } 
          } 
          return -1 
         } 
        } 
        if (!Array.prototype.map) { 
         Array.prototype.map = function(e) { 
          var t = []; 
          for (var n = 0, r = this.length; n < r; n++) { 
           t.push(e(this[n])) 
          } 
          return t 
         } 
        } 
        var isArray = function(e) { 
         return Object.prototype.toString.call(e) === "[object Array]" 
        }; 
        var isFunc = function(e) { 
         return Object.prototype.toString.call(e) === "[object Function]" 
        }; 
        var ready = function(e, t) { 
         function u() { 
          if (!n) { 
           if (!t.body) return setTimeout(u, 13); 
           n = true; 
           if (i) { 
            var e, r = 0; 
            while (e = i[r++]) e.call(null); 
            i = null 
           } 
          } 
         } 

         function a() { 
          if (r) return; 
          r = true; 
          if (t.readyState === "complete") return u(); 
          if (t.addEventListener) { 
           t.addEventListener("DOMContentLoaded", s, false); 
           e.addEventListener("load", u, false) 
          } else { 
           if (t.attachEvent) { 
            t.attachEvent("onreadystatechange", s); 
            e.attachEvent("onload", u); 
            var n = false; 
            try { 
             n = e.frameElement == null 
            } catch (i) {} 
            if (b.doScroll && n) f() 
           } else { 
            o = e.onload; 
            e.onload = function(e) { 
             o(e); 
             u() 
            } 
           } 
          } 
         } 

         function f() { 
          if (n) return; 
          try { 
           b.doScroll("left") 
          } catch (e) { 
           setTimeout(f, 1); 
           return 
          } 
          u() 
         } 
         var n = false, 
          r = false, 
          i = [], 
          s, o; 
         if (t.addEventListener) { 
          s = function() { 
           t.removeEventListener("DOMContentLoaded", s, false); 
           u() 
          } 
         } else { 
          if (t.attachEvent) { 
           s = function() { 
            if (t.readyState === "complete") { 
             t.detachEvent("onreadystatechange", s); 
             u() 
            } 
           } 
          } 
         } 
         return function(e) { 
          a(); 
          if (n) { 
           e.call(null) 
          } else { 
           i.push(e) 
          } 
         } 
        }(w, d); 
        if (w.addtocalendar && typeof w.addtocalendar.start == "function") return; 
        if (!w.addtocalendar) w.addtocalendar = {}; 
        addtocalendar.languages = { 
         de: "In den Kalender", 
         en: "Add to Calendar", 
         es: "Añadir al Calendario", 
         fr: "Ajouter au calendrier", 
         hi: "कैलेंडर में जोड़ें", 
         "in": "Tambahkan ke Kalender", 
         ja: "カレンダーã«è¿½åŠ ", 
         ko: "캘린ë」ì— ì¶」ê°€", 
         pt: "Adicionar ao calendário", 
         ru: "Ð」обавить в календарь", 
         uk: "Ð」одати в календар", 
         zh: "æ·»åŠ åˆ°æ—¥åŽ†" 
        }; 
        addtocalendar.calendar_urls = {}; 
        addtocalendar.loadSettings = function(element) { 
         var settings = { 
          language: "auto", 
          "show-list-on": "click", 
          calendars: ["iCalendar", "Google Calendar", "Outlook", "Outlook Online", "Yahoo! Calendar"], 
          secure: "auto", 
          "on-button-click": function() {}, 
          "on-calendar-click": function() {} 
         }; 
         for (var option in settings) { 
          var pname = "data-" + option; 
          var eattr = element.getAttribute(pname); 
          if (eattr != null) { 
           if (isArray(settings[option])) { 
            settings[option] = eattr.replace(/\s*,\s*/g, ",").replace(/^\s+|\s+$/g, "").split(","); 
            continue 
           } 
           if (isFunc(settings[option])) { 
            var fn = window[eattr]; 
            if (isFunc(fn)) { 
             settings[option] = fn 
            } else { 
             settings[option] = eval("(function(mouseEvent){" + eattr + "})") 
            } 
            continue 
           } 
           settings[option] = element.getAttribute(pname) 
          } 
         } 
         return settings 
        }; 
        addtocalendar.load = function() { 
         ready(function() { 
          var e = { 
           iCalendar: "ical", 
           "Google Calendar": "google", 
           Outlook: "outlook", 
           "Outlook Online": "outlookonline", 
           "Yahoo! Calendar": "yahoo" 
          }; 
          var t = -(new Date).getTimezoneOffset().toString(); 
          var n = addtocalendar.languages; 
          var r = document.getElementsByTagName("*"); 
          for (var i = 0; i < r.length; i++) { 
           var s = r[i].className; 
           if (s.split(" ").indexOf("addtocalendar") != -1) { 
            var o = addtocalendar.loadSettings(r[i]); 
            var u = o["calendars"].length == 1; 
            var a = "http:"; 
            if (o["secure"] == "auto") { 
             a = location.protocol == "https:" ? "https:" : "http:" 
            } else if (o["secure"] == "true") { 
             a = "https:" 
            } 
            var f = a + atc_url; 
            var l = r[i].id; 
            var c = n["en"]; 
            if (o["language"] == "auto") { 
             var h = "no_lang"; 
             if (typeof navigator.language === "string") { 
              h = navigator.language.substr(0, 2) 
             } else if (typeof navigator.browserLanguage === "string") { 
              h = navigator.browserLanguage.substr(0, 2) 
             } 
             if (n.hasOwnProperty(h)) { 
              c = n[h] 
             } 
            } else if (n.hasOwnProperty(o["language"])) { 
             c = n[o["language"]] 
            } 
            var p = ["utz=" + t, "uln=" + navigator.language, "vjs=" + atc_version]; 
            var d = r[i].getElementsByTagName("var"); 
            var v = -1; 
            for (var m = 0; m < d.length; m++) { 
             var g = d[m].className.replace("atc_", ""); 
             var y = d[m].innerHTML; 
             if (g == "event") { 
              v++; 
              continue 
             } 
             if (g == d[m].className) { 
              if (g == "atc-body") { 
               c = y 
              } 
              continue 
             } 
             if (v == -1) { 
              continue 
             } 
             p.push("e[" + v + "][" + g + "]" + "=" + encodeURIComponent(y)) 
            } 
            var b = l == "" ? "" : l + "_link"; 
            var w = document.createElement("ul"); 
            w.className = "atcb-list"; 
            var E = ""; 
            var S = ""; 
            for (var x in o["calendars"]) { 
             if (!e.hasOwnProperty(o["calendars"][x])) { 
              continue 
             } 
             var T = e[o["calendars"][x]]; 
             var N = l == "" ? "" : 'id="' + l + "_" + T + '_link"'; 
             var C = f + T + "?" + p.join("&"); 
             if (u) { 
              S = C 
             } else { 
              E += '<li class="atcb-item"><a ' + N + ' class="atcb-item-link" href="' + C + '" target="_blank">' + o["calendars"][x] + "</a></li>" 
             } 
            } 
            w.innerHTML = E; 
            if (r[i].getElementsByClassName("atcb-link")[0] == undefined) { 
             var k = document.createElement("a"); 
             k.className = "atcb-link"; 
             k.innerHTML = c; 
             k.id = b; 
             k.tabIndex = 1; 
             if (u) { 
              k.href = S; 
              k.target = "_blank" 
             } 
             r[i].appendChild(k); 
             if (!u) { 
              r[i].appendChild(w) 
             } 
            } else { 
             var k = r[i].getElementsByClassName("atcb-link")[0]; 
             if (!u) { 
              k.parentNode.appendChild(w) 
             } 
             k.tabIndex = 1; 
             if (k.id == "") { 
              k.id = b 
             } 
             if (u) { 
              k.href = S; 
              k.target = "_blank" 
             } 
            } 
            r[i].getElementsByClassName("atcb-link")[0].addEventListener("click", o["on-button-click"], false); 
            var L = r[i].getElementsByClassName("atcb-item-link"); 
            for (var m = 0; m < L.length; m++) { 
             L[m].addEventListener("click", o["on-calendar-click"], false) 
            } 
           } 
          } 
         }) 
        }; 
        addtocalendar.load() 
       })(window, document) 
      } 
     }; 
     }); 

UPDATE/ANSWER 由於@charlietfl,答案是包括$超時,以便Angular可以在jQuery插件之前加載,例如:

'use strict'; 

angular.module('myApp') 
    .directive('addtocalendartest', function($timeout) { 
    return { 
     restrict: 'A', 
     link: function(scope, element, attrs) { 
     $timeout(function(){ 
      // jQuery plugin logic goes here 
     }, 5000); 
     } 
    }; 
}); 
+1

時間模板假設它從文本中獲取價值,你可能需要使用'$超時「讓角編譯第一 – charlietfl

+0

就是這樣 - 謝謝! –

+0

雖然不需要5秒鐘,但可能不需要設置任何持續時間,除非數據正從服務器中拉出....路由中的「解析」將幫助解決這個問題 – charlietfl

回答

1

使用$timeout先讓角度先編譯文本,以便插件不會嘗試讀取表達式。

$timeout(function(){ 
    addtocalendar.load(); 
}); 

如果需要將數據從服務器請求解決首先你可以在路由器使用resolve,以便它存在於被載入

+0

答案真的很好一個孩子狀態到另一個狀態,但我只是用分頁來測試它,它似乎不工作。你有任何建議,使其與分頁工作?如果我翻閱一頁到下一頁,我會回到沒有任何按鈕出現。 –

+0

一個[plunker](http://plnkr.co/edit/?p=catalogue)演示將幫助 – charlietfl

+0

結束了我的目的。分頁工作也很棒。再次感謝你的幫助! –