AngularJs将当前浏览器选项卡中的更改反映到其他选项卡

时间:2015-01-08 03:36:07

标签: angularjs

使用此代码,angularjs是否支持绑定,该绑定也会反映您正在使用的其他标签中的当前标签中的更改

<input type="text" ng-model="name"><span ng-bind="name"></span>

2 个答案:

答案 0 :(得分:4)

不,不仅仅使用该代码。

但是,我刚刚写了一条很好的指令供您使用ng-modelng-bind(但不仅适用于{{ inline expressions }})。

Here it is in action

以下是代码:

/**
 * sync-between-tabs directive.
 * Use in conjunction with ng-model or ng-bind to synchronise the contents
 * between tabs. The value is synced using localStorage, so each thing to sync
 * needs a unique key. Specify the key using the sync-between-tabs attribute
 * value, or leave blank to use the ng-model or ng-bind attributes.
 * Example usage:
 *    <input ng-model="some.thing" sync-between-tabs></input>
 *         uses the key "some.thing"
 *    <input ng-model="some.thing" sync-between-tabs="UNIQUEKEY25"></input>
 *         uses the key "UNIQUEKEY25"
 *    <span ng-bind="some.other.thing" sync-between-tabs></span>
 *         uses the key "some.other.thing"
 *    <span ng-bind="name" sync-between-tabs="UNIQUE_KEY_12"></span>
 *         uses the key "UNIQUE_KEY_12"
 */
app.directive('syncBetweenTabs', ['$window', '$parse',
  function($window, $parse) {
    var callbacks = {}, keysToWatch = [];
    var localStorage = {
      key: function(key) {
        return '__syncValue_' + (key || '').replace('__syncValue_', '');
      },
      getItem: function(key) {
        return $window.localStorage.getItem(localStorage.key(key));
      },
      setItem: function(key, val) {
        $window.localStorage.setItem(localStorage.key(key), val);
      },
      onItemChange: function(key, callback) {
        key = localStorage.key(key);
        var keyAlreadyExists = false;
        if (keysToWatch.indexOf(key) < 0) {
          keysToWatch.push(key);
          callbacks[key] = [callback];
        } else {
          callbacks[key].push(callback);
          keyAlreadyExists = true;
        }
        return function deregister() {
          if (!keyAlreadyExists)
            keysToWatch = without(keysToWatch, key);
          callbacks[key] = without(callbacks[key], callback);
          if (callbacks.length === 0)
            delete callbacks[key];
        };
      }
    };

    function without(arr, value) {
      var newArr = [];
      for (var i = 0, len = arr.length; i < len; ++i) {
        if (arr[i] !== value)
          newArr.push(arr[i]);
      }
      return newArr;
    }

    if ($window.addEventListener) {
      $window.addEventListener("storage", handle_storage, false);
    } else {
      $window.attachEvent("onstorage", handle_storage);
    }

    function handle_storage(e) {
      if (!e) e = $window.event;
      if (callbacks[e.key])
        angular.forEach(callbacks[e.key], function(callback) {
          callback(e.newValue);
        });
    }

    return {
      restrict: 'A',
      require: '?ngModel',
      link: function(scope, elem, attrs, ngModelCtrl) {
        var key = attrs['syncBetweenTabs'],
          mode = 'unknown',
          dereg, ngBindExpr
        if (ngModelCtrl) {
          mode = 'ngModel';
          if (!key)
            key = attrs['ngModel'];
        } else if (attrs['ngBind']) {
          mode = 'ngBind';
          if (!key)
            key = attrs['ngBind'];
        } else {
          throw new Error('sync-between-tabs only works for ng-model and ng-bind at present');
        }
        if (mode == 'ngModel') {
          ngModelCtrl.$viewChangeListeners.push(function() {
            localStorage.setItem(key, ngModelCtrl.$viewValue);
          });
          var currentValue = localStorage.getItem(key);
          if (currentValue && currentValue !== ngModelCtrl.$viewValue) {
            ngModelCtrl.$setViewValue(currentValue);
            ngModelCtrl.$render();
          }
          dereg = localStorage.onItemChange(key, function(value) {
            ngModelCtrl.$setViewValue(value);
            ngModelCtrl.$render();
          });
        } else {
          ngBindExpr = $parse(attrs['ngBind']);
          dereg = localStorage.onItemChange(key, function(value) {
            ngBindExpr.assign(scope, value);
            scope.$digest();
          });
        }
        scope.$on('$destroy', dereg);
      }
    }
  }
]);

答案 1 :(得分:1)

假设两个选项卡在同一个域下加载了相同的站点,您可以使用本地/会话存储或cookie发布共享数据并使其可用于任何选项卡,这是您必须不断检查更改的缺点。但它应该工作