Подтвердить что ты не робот

Включить внешний js-виджет в шаблон angular

Мне нужно включить тег script, который отобразит виджет на моем шаблоне angularjs.

Например, я бы включил этот

<script type="text/javascript" src="http://100widgets.com/js_data.php?id=106"></script>

Но angular не отобразит его.

4b9b3361

Ответ 1

Так как скрипты 100widgets обрабатывают DOM и добавляют другие теги <script> в HTML файл, он не может работать должным образом. Morover некоторые из этих виджетов основаны на Flash, поэтому script добавить ссылку на объекты SWF. Я думаю, что одна из возможностей заключается в анализе вывода запроса на url в атрибуте src (в вашем примере http://100widgets.com/js_data.php?id=106) и попытке добавить соответствующий DOM-манипуляции и скрипты в шаблон, в котором вы хотите видеть виджет.

Ниже приведен пример страницы (стр. 1) НЕ РАБОТАЕТ (просто добавлен тег script при вводе) и вторая страница (страница2), в шаблоне которой есть вставки, необходимые для отображения виджета календаря.

PS: из-за ограничений в песочнице этот фрагмент не мог работать здесь на SO; попробуйте эту версию CodePen в режиме отладки: http://codepen.io/beaver71/pen/MyjBoP или создайте собственную версию, развернутую на вашем локальном веб-сервере.

(function() {
  'use strict';

  angular.
  module('myApp', ['ui.router']).
  config(configRouteProvider).
  controller('AppCtrl', AppCtrl);

  function AppCtrl($location, $rootScope) {
    $rootScope.$on('$stateChangeStart', onStateChangeStart);

    function onStateChangeStart(event, toState, toParams, fromState, fromParams, options) {
      console.log('From:', fromState.name,
        'to:', toState.name);
    }
  }

  function configRouteProvider($stateProvider, $urlRouterProvider) {
    $stateProvider
      .state('home', {
        url: '/',
        templateUrl: 'views/home.html'
      })
      .state('page1', {
        url: '/pag1',
        templateUrl: 'views/page1.html',
      })
      .state('page2', {
        url: '/pag2',
        templateUrl: 'views/page2.html',
      });
    $urlRouterProvider.otherwise('/');
  }

}());
body {
  margin: 0px;
}
hr {
  margin: 0px;
}
.tabs {
  padding: 8px;
  background-color: black;
  color: white;
}
.tabs a,
.tabs a:visited,
.tabs a:active,
.tabs a:hover {
  color: white;
}
.my-tab {
  height: 100%;
  width: 100%;
  position: absolute;
  padding: 8px;
}
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
  <script src='https://code.angularjs.org/1.4.0/angular.min.js'></script>
  <script src='https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js'></script>
</head>

<body ng-app="myApp" ng-controller="AppCtrl as app">
  <div class="tabs">
    <a href="#" ui-sref="home">Home</a>
    <a href="#" ui-sref="page1">Page1</a>
    <a href="#" ui-sref="page2">Page2</a>
  </div>
  <hr />
  <div ui-view></div>

  <script id="views/home.html" type="text/ng-template">
    <div class="my-tab">
      <h3>Home</h3>
      <p>bla bla bla</p>
    </div>
  </script>

  <script id="views/page1.html" type="text/ng-template">
    <div class="my-tab">
      <h3>Page1</h3>
      <p>Using script type="text/javascript"... NOT WORKING:</p>
      <script type="text/javascript" src="http://100widgets.com/js_data.php?id=106"></script>
    </div>
  </script>

  <script id="views/page2.html" type="text/ng-template">
    <div class="my-tab">
      <h3>Page2</h3>
      <p>Workaround</p>
      <!--code1-->
      <div class="scriptcode">
        <!--ecode1-->
        <a target='_blank' href='http://100widgets.com/calendars/106-calendar.html'>
          <embed align="middle" id="calendar" width="170" height="156.111111111" allowscriptaccess="always" quality="high" salign="lt" wmode="transparent" src="http://100widgets.com/js-files/postit.swf?UTCoffset=0&amp;gid=0&amp;text1=St Valentines is on 14th February 2012&amp;&amp;event_time=&amp;rec=&amp;rnd=0&amp;gha=0&amp;ghb=0&amp;ghf=1&amp;gbc=FFB200&amp;gfc=040244&amp;gtc=F9F9FF&amp;gnu=http://mycalendar.org/widget/&amp;fna=&amp;ims="
          type="application/x-shockwave-flash" />
        </a>
        <!--code2-->
      </div>
      <!--ecode2-->
      <!--below commented cause it not necessary -->
      <!--script type="text/javascript">
        var js = document.createElement("script");
        js.type = "text/javascript";
        js.src = "http://100widgets.com/stat.js.php";
        document.body.appendChild(js);
      </script-->
    </div>
  </script>
</body>

Ответ 2

Из-за ограничений безопасности Angular не анализирует теги <script> внутри шаблонов.
Затем виджет, на который вы ссылаетесь, использует document.write. Document.write недоступен после загрузки вашей страницы.
Таким образом, здесь, кажется, нет простого выхода.

Однако, поскольку то, что вы пытаетесь сделать, является обычным для add- script, krux созданным postscribe. Способ решения этой проблемы. В свою очередь я создал небольшую директиву, которая использует эту библиотеку.

В шаблоне он будет выглядеть примерно так:

<div ps-src="http://100widgets.com/js_data.php?id=21"></div>

директива:

  function psScr($document) {
    return {
      restrict: 'A',
      scope: {
        psSrc: '@'
      },
      link: link
    }

    function link(scope, elm) {
      if (typeof postscribe !== 'undefined') {
        postscribe(elm[0], `<script src='${scope.psSrc}'></script>`);
      } else {
        // If postscibe isn't loaded, first load the needed libarary
        var script = document.createElement('script');
        script.src = 'https://gitcdn.xyz/repo/krux/postscribe/master/dist/postscribe.js';
        script.onload = function () {
          // once postscibe is in, kick it into action.
          link(scope,elm); 
        };
        document.head.appendChild(script);
      }
    }
  }

  angular.module('psSrcModule', [])
    .directive('psSrc', psScr);

Вы можете видеть его в действии в этой панели

Не все виджеты ведут себя красиво в сочетании с postscribe, хотя некоторые из них, похоже, отображают некоторые артефакты в html. В настоящее время мне не хватает времени, чтобы узнать, кто виноват в этом (100widgets или postscribe), но если вам это действительно нужно, это то, что можно отработать.