在指令之外调用范围变量

时间:2016-03-07 21:59:24

标签: javascript jquery html angularjs jquery-ui

我正在使用juqeryUi draggable来拖动div。我正在存储拖拽到localStorage内部的位置,以便在刷新页面时它位于同一位置。我现在要做的是将位置存储在局部变量中,并将值分配给另一个div。

的index.html

    <!DOCTYPE html>
    <html lang="en" ng-app="container">
    <head>
      <meta charset="utf-8">
      <title>efoli</title>

      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
      <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
      <script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
      <script type="text/javascript" src="js/angular.min.js"></script>
      <script type="text/javascript" src="containers.js"></script>

      <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
      <link rel="stylesheet" href="Style/design.css">
    </head>
      <body ng-controller="ContainerController as contain">

        <div id="grid" ng-hide="editing"></div>
        <div class="drag resize {{item.class}}" ng-repeat="item in block" id="{{item.id}}" ng-hide="editing" edit>
          <h1>{{item.title}}</h1>

  <!-- ------- Wont show anything--------- -->
          <h2>{{topPosition}}</h2>
          <textarea type="text" id="{{item.id}}" style="display:table-cell; width:inherit; height:inherit"></textarea>
        </div>
      </body>
    </html>

Containers.js

(function() {
  var app = angular.module('container', []);
  app.controller('ContainerController', ['$scope', function($scope) {
    $scope.block = [
      { "id" : "1",
        "class":"fname",
        "title" : "First Name",
        "text":""},
      { "id" : "2",
        "class":"lname",
        "title" : "Last Name",
        "text" : ""},
      { "id" : "3",
        "class":"education",
        "title" : "Education",
        "text" :""},
      { "id" : "4",
        "class":"contact",
        "title" : "Contact",
        "text" : ""},
      { "id" : "5",
        "class":"experience",
        "title" : "Experience",
        "text" : ""}
    ];
  }]);

  app.directive('edit', function(){
    return {
      restrict:'A',
      link: function($scope) {
        angular.element(document).ready(function() {
          var sPositions = localStorage.positions || "{}",
          positions = JSON.parse(sPositions);

          $.each(positions, function (id, pos) {
            $("#" + id).css(pos)
          });

          $('.drag').draggable({
            grid:[25,25],
            scroll: false,
            stop: function (event, ui) {
              positions[this.id] = ui.position
              $scope.topPosition = positions[this.id].top;
              $scope.leftPosition = positions[this.id].left;
              localStorage.positions = JSON.stringify(positions)
            }
          }); ...

在index.html中,当我调用topPosition时,没有任何内容填充。我在.draggable()里面运行了一个console.log,我得到了顶级位置的值,但是当我在.draggable之外运行console.log时,我得到了未定义。我猜测范围变量只是本地的,但我想知道如何使其全局化,以便我可以在不同的地方使用这些值。

2 个答案:

答案 0 :(得分:0)

在控制器中声明范围变量as,

DSL::Constants::MY_CONSTANT # => 1
MY_CONSTANT # => NameError: uninitialized constant MY_CONSTANT
Object.instance_eval { include DSL::Constants }
MY_CONSTANT # => 1

并通过使用父作用域调用变量将topPosition值赋给指令中的变量,如

$scope.topPosition = ""; //in the container controller

在可拖动的内部,

var parentScope = $scope.$parent; // inside the edit directive

此范围变量可用于指令中的其他事件以及控制器中。

请找到修改后的PLUNKER。希望它有所帮助。

答案 1 :(得分:0)

这里没有范围问题。 问题是draggable不是angular知道的东西,所以当我们与draggable 交互时,不会调用摘要周期。

您可以通过调用ClockKit或将代码包含在内部调用scope.$apply()的内容中来解决此问题,例如$apply()。这样做是为了告知角度某些事情已发生变化,并且需要检查手表并更新绑定。

您可以在此plnkr中查看此操作。 (请注意,您需要进行拖动,因为$timeout仅添加到topPosition事件中的范围内

待办事宜(学习并实施,阅读docs):

现在您可以看到所有绑定都具有相同的值,这是预期的,因为它们都共享相同的范围。要解决此问题,您应该使用隔离范围(详细说明超出了答案的范围)。

另外需要注意的是,你的指令在stop中,因此可以为每个元素调用,不需要使用全局选择器(,你不应该在指令中使用全局选择器) )与ng-repeat类似,应为$('.drag').draggable()

也会在创建元素后调用link,因此也不需要element.draggable()

此外,您应该使用angular.element(document).ready(getItem()等与localstorage进行互动。