在AngularJS指令中包装jQuery插件

时间:2015-10-04 19:38:43

标签: jquery angularjs

根据答案here,我一直在尝试将一个jQuery插件(addtocalendar)包装在一个angular指令中。我正在使用ui-router,以前插件可以工作,但如果我从这个孩子导航到另一个状态,addtocalendar按钮将完全消失。

现在,将插件包装在一个指令中,如果我导航到另一个子状态然后返回,我能够看到该按钮,但是,我从插件中得到一个错误,我指定了一个无效日期。似乎我从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,答案是包含$ timeout,以便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 个答案:

答案 0 :(得分:1)

使用$timeout让angular首先编译文本,以便插件不会尝试读取表达式。

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

如果需要首先从服务器请求解析数据,您可以在路由器中使用resolve,以便在模板加载时存在