Angular作用域和ng-click / ng-show用于设置多个div

21 浏览
0 Comments

Angular作用域和ng-click / ng-show用于设置多个div

我正在寻求帮助,解决我已经有的代码。

主要目标是能够点击任何加号图标,并在其他所有div块上放置一个覆盖层。

并且当点击加号图标时,它还会在右侧显示一个div块。

当单击块2时,您将看到它实现了所有用途。

当任何加号图标被点击时,我正在寻找一种有效的方法来使用Angular实现这一点。

这只是我在此处展示的一个小样本,实际上会有10到20个块需要覆盖。

如果有人能看到一种使用更少的代码,并更好地利用作用域的方法,那将非常感激。

我已经看过许多选项,比如在这里的帖子中。

试过了,但它不想工作...

data-ng-class="{coverThisBlock: value2 == 'off',coverThisBlock: value == 'on'}"

如果我必须使用这种类型的选项,甚至说10个块,那将是一团糟。

主要问题

有没有更好的Angular方法使其起作用...当单击任何加号图标时,它会更改作用域,然后被ngclass和ng-show使用?

如何在此示例中正确连接作用域?

非常感谢。

我已经设置了一个工作中的FIDDLE HERE

\"enter

这是Avijit Gupta的最终工作示例

\"enter

 

1 Hello

2 Hello

3

4 Hello

5 Hello

回答与ng-repeat有关的问题

ng-repeat可以为每个不同的div使用多个CSS类吗

显然可以。

通过使用类似于这样的作用域id...


和CSS像这样...

.block-1 {...

这里有工作示例

admin 更改状态以发布 2023年5月22日
0
0 Comments

更新

糟糕,每次只能选择一个。嗯...我写的大部分内容都适用。

新的 Fiddle

唯一的区别是JavaScript。我们不再有一个所选块的数组,而是有一个代表所选块的数字。

this.blocks = Array.apply(null, Array(10)).map(function (val, index) {return index;});
this.activeIndex = null;
this.isActive = function(index) {
    return that.activeIndex === index;
};
this.hasSelected = function() {
    return that.activeIndex !== null;
};
this.selectBlock = function(index) {
    if (that.activeIndex === index) {
        that.activeIndex = null;
    } else {
        that.activeIndex = index;
    }
};

看,好的JavaScript代码很容易维护,即使需求发生变化(或我发现它们发生了变化)。

(实际上,我们可以不使用这些辅助函数,但是我们使用它们是为了更漂亮的代码和可能的封装。)


原始答案

这里有Fiddle

我希望我已经解释了为什么我们应该在Fiddle中做这些事情,并提供了可靠的参考/进一步阅读材料。

先搞清楚

  • 不要使用 $scope。我喜欢 controller as 语法。在JS中,你使用 this.prop 和HTML中,你使用 myCtrlAs.prop文档
  • 这是一个CSS问题。利用:not()

两个原则:KISS和DRY

所以我们有一个同样复制粘贴的代码块问题。就像 @avijit 说的,你应该使用 ng-repeat 指令。

    //This entire block will be repeated

对于每一行,我们需要跟踪它是否被选中。遵循KISS原则,唯一需要跟踪的状态就是这个

否则,事情会变得太复杂。

  //each element represents the state of a row
  this.blocks = [0,0,0,0,0]; 

所以这个块数组用于 ng-repeat


你会问,我们如何跟踪哪些要变暗,哪些是活动的?

答案是...等着吧。

你不用跟踪

相反,我们使用在控制器上的函数获取有关单个 blocks 变量的信息。你可以反对我的措辞,但请注意我说了“跟踪”吗?再次强调,不要存储重复的状态数据。根据我的经验,这变成了一场噩梦。

(实际上,我们可以不使用这些辅助函数,但是我们使用它们是为了更漂亮的代码和可能的封装。)

所以我想指出的第一个函数是:

this.hasSelected = function() {
  return that.blocks.indexOf(true) !== -1;
};

这是用来做什么的?你说对了!是为了确定是否应该“遮盖”未选中的行。

使用CSS-它很有用!

所以我们有条件地应用 .has-selected 类到包装器上。

所以,只有当它有一个 .has-selected 的祖先时,“封面”才适用,我们有

has-selected :not(.active) > .col-sm-4 {
  width: 33%;
  height: inherit;
  background-color: rgba(00,00,00,0.8);
  z-index: 9;
}
.has-selected :not(.active) .col-sm-4 {
  @media (max-width:420px){
    width: 80%;
  }
}  

回到 ng-repeat

哦,到现在为止,你应该知道 $index 被用于访问当前HTML在 ng-repeat 中的索引。(文档和 SO 线程)

          {{$index}}

结论

  • 阅读文档
  • 不要试图用一个工具做所有的事情
  • 如果你认为我没有特别好地解释某些东西,只需询问。

另外,我认为我破坏了一些样式。希望你能自己修复它。

0
0 Comments

编辑 (根据提问者的评论):

更新的JSFiddle链接

  1. 只能有一个被点击吗?或者如果另一个被打开/点击,第一个被打开的将被重置和关闭

这将使您的代码简化近2倍。

初始状态:

  • 没有选择任何块。
  • 没有块被覆盖。

代码:

$scope.setToInitialState = function() {
  $scope.blocks.forEach(function(block) {
    $scope.isSelected[block.id] = false;
    $scope.isCovered[block.id] =  false;
  });
};

触摸状态:

  • 切换所点击块的选择状态。(在选择和取消选择之间切换)
  • 如果选择,则覆盖和取消选择所有其他块。
  • 如果取消选择,则将应用程序带回初始状态。

代码:

$scope.selectBlock = function(id) {
  $scope.isSelected[id] = !$scope.isSelected[id];
  $scope.isCovered[id] = false;
  if ($scope.isSelected[id]) {
    $scope.blocks.forEach(function(block) {
      if (block.id !== id) {
        $scope.isCovered[block.id] = true;
        $scope.isSelected[block.id] = false;
      }    
    });
  }
  else {
    $scope.setToInitialState();
  }
};

  1. 演示使用相同的设置块大小,但实际使用的所有div块都具有不同的高度和宽度。并且每个块都是不同的图像

您应该考虑使用ng-src

假设您可能从DB检索所有这些内容。然后,如果可能,您可以将每个图像放在固定大小的div中,以使它们的大小相同。

  1. 另外,显示分为2个竖直半屏幕部分

可以通过稍微调整css来实现。


原始答案:

可工作的JSFiddle链接

假设您的应用程序具有2种状态:

  1. 初始状态(未触摸)
  2. 触摸状态

最初,您处于初始状态:

  • 没有显示正确的div。
  • 所有图标都是“加号”(没有“减去”)
  • 没有块被覆盖。

代码:

$scope.setToInitialState = function() {
  $scope.plusCount = 0;
  $scope.blocks.forEach(function(block) {
    $scope.isPlus[block.id] = true;
    $scope.isShowDiv[block.id] = false;
    $scope.isCoverBlock[block.id] = false;
    $scope.plusCount += 1;
  });
};

当您处于触摸状态时:

  • 所有具有“加号”图标的块都被覆盖。
  • 仅显示未覆盖的那些块的正确div。

代码:

// Run when user clicks on the 'plus' or 'minus' icon.
$scope.selectBlock = function(id) {
  $scope.isPlus[id] = !$scope.isPlus[id]; // toggle between 'plus' and 'minus' icons
  if ($scope.isPlus[id]) {
    $scope.plusCount += 1;
  }
  else {
    $scope.plusCount -= 1;
  }
  $scope.blocks.forEach(function(block) {
    if ($scope.isPlus[block.id]) {
      $scope.isCoverBlock[block.id] = true;
    }
    else {    
      $scope.isCoverBlock[block.id] = false;
    }
    $scope.isShowDiv[block.id] = !$scope.isCoverBlock[block.id];
  });
};

因此,基本上当用户与视图交互并实际点击图标时,他/她进入touched state(运行上面的代码)。

只有当所有图标都是'plus'时,用户必须被发送到initial state:

if ($scope.plusCount === $scope.blocks.length) {
  $scope.setToInitialState();
}

更改HTML代码:

  1. ng-init =“setToInitialState()”添加到最外面的div中,以便最初处于初始状态。

代码:


  1. 使用ng-repeat,而不是为每个块复制和粘贴代码:

代码:

        
{{block.id}} Hello

希望这对您有所帮助!

0