2017-02-07 2 views
10

Я хотел бы использовать Plupload в компоненте Angular2 и получить доступ к файлу JavaScript Plupload из CDN. Я хочу, чтобы он был специфичным для компонента, чтобы он не был загружен, если он не требуется - я хочу, чтобы он был в ленивом загруженном модуле. Как я могу это сделать?Angular2 with Typcript, как использовать файл сценария CDN Plupload в ленивом загруженном модуле?

Теперь полностью ответил на эту страницу!

В результате этого квеста, который включал предложение и награждение щедроты для двух людей, которые упорно работали со мной на этом, заключается в следующем:

  1. Пример использования Plupload с угловыми 2 и машинопись
  2. Как Лазы загрузить сценарий из CDN в угловом 2
  3. примера того, как использовать Plupload ленивым загруженного модуля
  4. Как использовать ленивый загруженный скрипт в радиально-2

    (См истории изменений для некрасивых деталей, которые используются, чтобы сделать этот вопрос.)

+0

Hi Reid. Вам все еще нужна помощь? – AngularChef

+0

@AngularFrance Он еще не решен. Поэтому я хотел бы, чтобы кто-то дал ответ. Если у вас есть это, это будет набухать. В противном случае, если никто не придет с относительно полным ответом, я буду работать над ним в ближайшие несколько дней, и если удастся, отправьте мой ответ. – Reid

+0

Я бы хотел нанести удар. Вы упоминаете файл сценария Pupload CDN и не испытываете проблем с использованием Pupload в обычной JS-среде, можете ли вы указать URL-адрес файла сценария CDN и, возможно, ссылку на простой пример JS Pupload, который вы хотите интегрировать с Angular? – AngularChef

ответ

2

Вот обзор того, что вам нужно сделать, чтобы создать ленивую загруженную функцию Plupload при загрузке Plupload из CDN:

  1. Когда функция необходима (например, пользователь нажимает кнопку или посещение страницы) , динамически добавьте тег <script> на страницу, чтобы загрузить библиотеку Plupload из CDN.
  2. Подождите, пока библиотека не будет загружена, чтобы продолжить (или вы можете получить ошибку "plupload is undefined").
  3. Отобразить пользовательский интерфейс для взаимодействия с Plupload в одном из ваших угловых шаблонов. В своей простейшей форме этот пользовательский интерфейс состоит из двух кнопок: «Выбрать файлы» и «Загрузить файлы».
  4. Инициализировать Plupload и подключить его к пользовательскому интерфейсу.

Полный рабочий код: https://plnkr.co/edit/4t39Rod4YNAOrHmZdxqc?p=preview

Пожалуйста, обратите внимание на следующие моменты в моей реализации:

  • Что касается # 2. Лучшим способом проверить, закончилась ли загрузка Plupload, является опрос глобального пространства имен для существования переменной plupload. Пока window.plupload не существует, это значит, что библиотека еще не загружена и что мы НЕ должны продолжать. Для простоты мой код просто ждет одну секунду и продолжается.
  • Номер 4 может показаться немного сложным. Plupload сильно использует прямой доступ DOM для подключения своего API к HTML (например, document.getElementById('filelist')). Это то, что угловатое препятствует и что вы должны стараться избегать, когда это возможно. Более конкретно прямой доступ DOM используется в следующих местах:
    • Рассказывать Plupload, который DOM элемент должен вызвать в «Выбрать файлы» Диалог (что они называют опцию browse_button конфигурации). Для этого я не мог избежать прямой ссылки DOM, и я использовал декоратор @ViewChild, чтобы удержать кнопку «Выбрать файлы».
    • Чтобы отобразить выбранные файлы в шаблоне. Для этого я преобразовал синтаксис Plupload в регулярный синтаксис углов. Я подталкиваю выбранные файлы к свойству класса fileList, которое я показываю в шаблоне, используя стандарт *ngFor.
    • Кнопка «Загрузить файлы» запускает код, который выполняет фактическую загрузку и обновляет пользовательский интерфейс, чтобы показать ход загрузки. Еще раз, я преобразовал это в регулярный Угловой синтаксис, используя привязку события и привязку данных.

Позвольте мне знать, если у вас есть какие-либо вопросы.

+0

Одна проблема заключается в загрузке plupload в index.html. Исправьте это и обновите свою ссылку в своем ответе. Во-вторых, я не могу присудить вам 50 очков, потому что я уже получил награду за этот ответ, поэтому я вынужден присудить вам 100 очков за каждое обязательство награждать вас очками. Я не позволю мне сделать это до 24 часов после того, как я опубликую его, что у меня есть. В-третьих, поскольку ваш ответ не указан в запрошенной форме (с ленивыми загруженными компонентами), и первым (первым) ответчиком был ящик (другой ответчик), я буду проверять его как ответ, если у кого-то нет супер ответа. Спасибо. – Reid

+0

Вы можете быть супер-ответчиком, так как ответ лазера имеет ошибку типа при нажатии кнопки загрузки, тогда как ваш работает отлично. Если бы вы могли переносить его на ленивый загрузчик, минимально модифицировав плункер, связанный с моим вопросом, это было бы супер и ясным доказательством. В противном случае мне придется перенести его сам, чтобы увидеть. – Reid

+0

Эй. Не уверен, что вы подразумеваете под «ваш ответ не с ленивым компонентом». Компонент Pupload явно ленивый (он же загружен по требованию) в моем Plunkr. – AngularChef

2

В этом подходе нет необходимости в каких-либо дополнительных модулей загрузчика.

Смотрите пример (проверьте консоль WooHoo): http://plnkr.co/edit/gfUs4Uhe8kMGzPxwpBay?p=preview обновленный plunker: https://plnkr.co/edit/leG062tg7uX8sLrA0i2i?p=preview

Вы можете LazyLoad некоторые JS, добавив URL скрипта вам документ:

Создать my-lazy-load.function.ts:

export function lazyload(url) { 
    // based on https://friendlybit.com/js/lazy-loading-asyncronous-javascript/ 

    let scripts = document.getElementsByTagName('script'); 
    for (let i = scripts.length; i--;) { 
     if (scripts[i].src.match(url)) return true; 
    } 

    let s = document.createElement('script'); 
    s.type = 'text/javascript'; 
    s.async = true; 
    s.src = url; 
    let x = document.getElementsByTagName('script')[0]; 
    x.parentNode.insertBefore(s, x); 

    return true; 
} 

В вашей компании о том, что вы хотите добавить плуп:

import {lazyload} from "./my-lazy-load.function.ts"; 

export class MyComponent implements OnInit { 

    pluploadInterval:number = null; 
    hasPlupload: boolean = false; 

    ngOnInit() { 
     lazyload("https://cdnjs.cloudflare.com/ajax/libs/plupload/2.3.1/plupload.full.min.js"); 

     this.pluploadInterval = window.setInterval(()=>{ 
      if(window.plupload) { // you can check existence of plupload object any way you want 

       // Woohoo, I am ready to be used 

       this.hasPlupload = true; // everything is run outside ngZone, wrap it if angular2 is not reacting to changes, or change window.setInterval to setInterval 
       window.clearInterval(this.pluploadInterval); // don't forget to clean interval 
      } 
     }, 100); // timeinterval can vary 
.... 

Браузер автоматически загрузит это изображение.

Уведомление if(plupload) Предполагается, что добавлен глобальный объект plupload, который добавляет скрипт (я не знаю, действительно ли он добавлен, проверьте свой рабочий пример в чистом javascript). Как это расширение JQuery вы можете проверить это прототип, как это: jQuery test for whether an object has a method?

OLD ИСТОРИЧЕСКИЙ: @Reid здесь plunker: https://plnkr.co/edit/zDWWQbTQUSHBqCsrUMUi?p=preview plupload фактически загружен, но добавил требовать с define("plupload", ['./moxie'], extract); Я не уверен, что на данный момент как извлечь оттуда и какой пакет требует принадлежим ... коду для нахождения правильного загрузчика модуля принадлежит plupload себя, здесь (от plupload.dev.js):

if (typeof define === "function" && define.amd) { 
    define("plupload", ['./moxie'], extract); 
} else if (typeof module === "object" && module.exports) { 
    module.exports = extract(require('./moxie')); 
} else { 
    global.plupload = extract(global.moxie); 
} 
+0

Спасибо, но я ищу способ использовать Plupload, полученный из CDN, в среде TypeScript/Angular 2 - и делайте это с ленивой загрузкой. Таким образом, это фрагмент взаимосвязанных вещей, которые все должны объединить на стороне клиента. – Reid

+0

@ Исправьте код выше ленивой загрузки любых js из любого места (включая plupload из Интернета). Обычно вы пишете свое приложение plupload, как оно уже было (если у вас есть хорошие объявления, если вы не можете добавить «объявить let <имяofobject>: any;» в заголовке и использовать, как было объявлено. – laser

+0

Как только у меня есть решение, если никто больше не будет передо мной, я опубликую решение. То, что я ищу, - это не какие-то идеи, а пошаговый ответ. Конечно, ваш фон может сделать код и идеи, которые вы предложили, выглядят как все, что есть чтобы понять это, но у меня нет такого фона. Это то, что я ищу в качестве ответа, и я предоставлю, если найду его: http://stackoverflow.com/questions/23279259/mvc- 5-asp-net-identity-2-capture-users-preference-for-remember-me-in-externa/23304354 # 23304354 – Reid

1

Я думаю, что ваше Лучше всего использовать библиотеку Require.js, чтобы вы могли динамически загружать свои скрипты изнутри r компонентов.

Небольшой компромисс заключается в том, что вам придется добавить эту библиотеку 18 КБ на страницу index.html (CDN), однако это может сэкономить вам огромное количество загрузок, если ваши сторонние библиотеки массивны.

У меня нет опыта использования plupload, поэтому вместо этого я собрал следующий plunkr, который использует внешнюю анимационную библиотеку, взятую из CDN. Plunkr оживляет число от 0 - 100.

https://plnkr.co/edit/fJCtezsERYHOYplLh7Jo?p=preview


index.html

<script src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.3/require.min.js"></script> 

component.ts

ngOnInit(){ 
    // Dynamically loads the framework from the CDN. 
    require(["https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.1/TweenLite.min.js"], 
    // This function is then called ONCE LOAD IS COMPLETE 
    function (common) { 
     // Do greensock things 
     var demo = {score:0}, 
     scoreDisplay = document.getElementById("scoreDisplay"); 

     //create a tween that changes the value of the score property of the demo object from 0 to 100 over the course of 20 seconds. 
     var tween = TweenLite.to(demo, 20, {score:100, onUpdate:showScore}) 

     //each time the tween updates this function will be called. 
     function showScore() { 
     scoreDisplay.innerHTML = demo.score.toFixed(2); 
     } 
    }); 
    } 

Что мне нравится об этом подход, заключается в том, что в onL oad от require, синтаксис не изменяется от обычной реализации библиотеки, поэтому вы можете просто скопировать свой текущий рабочий код в обратный вызов.

+0

Спасибо за ваши усилия. Я думаю, что постараюсь сделать это без дополнительной библиотеки в это время. Я подозреваю, что на это может ответить только тот, кто использует Plupload в Angular2. – Reid

+0

Это решение может иметь потенциальную проблему (за исключением того, что он также не ленивый загружен). Я испытываю в angular2 beta, что некоторые загрузчики модулей конфликтуют с angular2 ('require' находится в глобальной области), когда у вас разные в tsconfig.json. Надеюсь, это уже не проблема. – laser

Смежные вопросы