11

我是 AngularJS 的新手,我一直无法找到加载两个不同 HTML 部分的列表和网格视图切换按钮的特定教程。阅读官方ng-includeng-switch官方文档并搜索 SO。不幸的是,我们不想使用UI-router

加载两个部分(list.htmlgrid.html)是正确的Angular编码方式吗?

网格视图

列表显示


我找到的最相关的帮助是:

1.http://tutorialzine.com/2013/08/learn-angularjs-5-examples(示例#5)

对示例 #5 有一个有见地的评论:

很好的简单例子 - 做得好。最后一个在网格视图和列表视图之间切换的示例效率不高,因为它同时创建了选项和显示/隐藏选项。更简单/更好的方法是使用带有中继器和 ng-switch 的单个 ul,然后使用 ng-switch-case 启用备用列表元素。- 约翰

2.http://www.adobe.com/devnet/html5/articles/getting-started-with-angularjs.html

3.https://stackoverflow.com/questions/12577378/create-a-single-html-view-for-multiple-partial-views-in-angularjs/12584774#12584774

4.https://stackoverflow.com/questions/15974086/conditional-ng-include-in-angularjs


我的 HTML 代码

<div class="col-xs-6" ng-controller="ToggleDisplayCtrl">
  <div class="btn-group select-format-container" ng-switch on="selected">
    <button ng-switch-when="true" ng-click="toggleGrid()" type="button"
      class="btn btn-primary" ng-model="formatChoice" ng-disabled="">grid</button>
    <button ng-switch-when="false" ng-click="toggleList()" type="button"
      class="btn btn-primary" ng-model="formatChoice" ng-disabled="">list</button>
  </div>
  <div ng-include src="formatChoice.url" scope="" onload=""></div>
</div>
<!-- col-xs-6  END ToggleDisplayCtrl-->

我的 JS 代码

'use strict';
var app = angular.module('tempApp');

app.controller('ToggleDisplayCtrl', function($scope) {
  $scope.formatChoices = [{
      name: 'grid',
      url: 'partials/grid.html'
    },
    {
      name: 'list',
      url: 'partials/list.html'
    }
  ];

  $scope.selected = true;
  $scope.toggleGrid = function() {
    if (selected) {
      return "partials/grid.html";
    }
    return "main.html";
  };
  $scope.toggleList = function() {
    if (selected) {
      return "partials/list.html";
    }
    return "main.html";
  };
});
4

6 回答 6

7

您应该定义应用程序控制器的范围属性,该属性将保存模板的 URL ng-include,并将此属性绑定到指令的范围。确保在指令中使用隔离作用域,以避免在修改指令作用域时产生副作用。这是一个这样做的例子(见代码中的注释):

JavaScript

angular.module('app', ['ngRoute'])
  .config(['$routeProvider', function($routeProvider) {
    $routeProvider
      .when('/main', {
        controller: 'appController',
        templateUrl: 'main.html'
      })
      .otherwise({
        redirectTo: '/main'
      });
  }])
  .controller('appController', ['$scope', function($scope) {
    $scope.view = 'list.html'; // <- default template used for ng-include
    $scope.data = [{
      text: '1'
    }, {
      text: '2'
    }, {
      text: '3'
    }, {
      text: '4'
    }, {
      text: '5'
    }, {
      text: '6'
    }];
  }])
  .directive('appView', function() {
    return {
      scope: {
        // link view property of directive's scope to some property
        // in the parent scope (scope of appController) specified in
        // app-view attribute of root element of directive
        view: '=appView'
      },
      replace: true,
      template:
        '<nav class="navbar navbar-default">' +
          '<div class="container">' +
            '<ul class="nav navbar-nav navbar-right">' +
              '<li ng-repeat="v in views" ng-bind="v.name" ' +
                  'ng-class="v.icon" ng-click="switchView(v)"></li>' +
            '</ul>' +
          '</div>' +
        '</nav>',
      link: function(scope, el, attr) {
        scope.views = [{
          name: 'List',
          template: 'list.html',
          icon: 'btn btn-default navbar-btn glyphicon glyphicon-th-list'
        }, {
          name: 'Grid',
          template: 'grid.html',
          icon: 'btn btn-default navbar-btn glyphicon glyphicon-th'
        }];
      },
      controller: ['$scope', function($scope) {
        $scope.switchView = function(view) {
          $scope.view = view.template; // <- modify parent scope view
        }
      }]
    }
  });

应用程序主页(index.html)

<html ng-app="app">
  ...
  <body ng-view=""></body>
</html>

路由模板 (main.html)

<header app-view="view"></header>
<section ng-include="view"></section>

列表视图模板 (list.html)

<div class="container">
  <div class="row">
    <div class="col-md-12 col-sm-12 panel panel-default" ng-repeat="item in data">
      <div class="panel-body">{{item.text}}</div>
    </div>
  </div>
</div>

网格视图模板 (grid.html)

<div class="container">
  <div class="row">
    <div class="col-md-4 col-sm-6 panel panel-default" ng-repeat="item in data">
      <div class="panel-body">{{item.text}}</div>
    </div>
  </div>
</div>

Plunker:http ://plnkr.co/edit/uWw7NuPG0I161mHXZg2r?p=preview

奖励:网格是响应式的,只需使用窗口大小播放一下

另外的选择:

正如您可能已经注意到grid.html并且list.html非常相似,因此如果您只有这两个选项,您可能决定根本不使用ng-include单独的可切换视图,而是将内容视图直接放入您的路由模板中,并使用ng-class指令切换面板中使用的类当视图改变时可以切换类。

路由模板 (main.html)

<header app-view="view"></header>
<section>
  <div class="container">
    <div class="row">
      <div ng-class="{'col-md-4': view === 'grid.html',
                      'col-md-12': view === 'list.html',
                      'panel':true, 'panel-default':true}"
           ng-repeat="item in data">
        <div class="panel-body">{{item.text}}</div>
      </div>
    </div>
  </div>
</section>
于 2014-03-17T07:54:25.097 回答
4

基本上,您需要做的是在同一页面上同时放置一个列表视图和网格,并一次显示一个,使用切换按钮在它们之间切换(更改 css 类)。我将在这里讨论示例#5:

范围内的第一个布局变量:

$scope.layout = 'grid';

以下是开关按钮:

<!-- On click change "$scope.layout = list" and if layout=='list' add class 'active' to self-->
<a href="#" class="list-icon" ng-class="{active: layout == 'list'}" ng-click="layout = 'list'"></a>

<!-- On click change "$scope.layout = grid" and if layout=='grid' add class 'active' to self-->
<a href="#" class="grid-icon" ng-class="{active: layout == 'grid'}" ng-click="layout = 'grid'"></a>

这些是网格和列表块:

<!-- Layout=='grid' if layout parameter is grid than show this block -->
<ul ng-show="layout == 'grid'" class="grid">...</ul>

<!-- Layout=='list' if layout parameter is list than show this block -->
<ul ng-show="layout == 'list'" class="list">...</ul>

使列表和网格布局的CSS:

/*-------------------------
  List layout
--------------------------*/

ul.list {
  list-style: none;
  width: 500px;
  margin: 0 auto;
  text-align: left;
}

ul.list li {
  border-bottom: 1px solid #ddd;
  padding: 10px;
  overflow: hidden;
}

ul.list li img {
  width: 120px;
  height: 120px;
  float: left;
  border: none;
}

ul.list li p {
  margin-left: 135px;
  font-weight: bold;
  color: #6e7a7f;
}
/*-------------------------
  Grid layout
--------------------------*/

ul.grid {
  list-style: none;
  width: 570px;
  margin: 0 auto;
  text-align: left;
}

ul.grid li {
  padding: 2px;
  float: left;
}

ul.grid li img {
  width: 280px;
  height: 280px;
  display: block;
  border: none;
}
于 2015-01-27T12:01:23.403 回答
4

最简单的方法是:

<div class="bar">
  <h1>Contacts</h1>
  <a href="#" class="list-icon" ng-class="{active: layout == 'list'}" ng-click="layout = 'list'"></a>
  <a href="#" class="grid-icon" ng-class="{active: layout == 'grid'}" ng-click="layout = 'grid'"></a>
</div>
<div ng-show="layout == 'list'" class="list">
<!-- Add your list page here -->
<div ng-show="layout == 'grid'" class="grid">
<!-- Add your grid page here -->

CSS:

/*
  Contacts bar with toggle switches
*/

.bar {
  background-color: #5c9bb7;
  background-size: 100% 100%;
  box-shadow: 0 1px 1px #ccc;
  border-radius: 2px;
  height: 100px;
  padding: 10px;
  position: relative;
  text-align: right;
  line-height: 1;
}

.bar a {
  background: #4987a1 center center no-repeat;
  width: 32px;
  height: 32px;
  display: inline-block;
  text-decoration: none !important;
  margin-right: 5px;
  border-radius: 2px;
}

.bar a.active {
  background-color: #c14694;
}

.bar a.list-icon {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAA GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOkYzNkFCQ0ZBMTBCRTExRTM5NDk4RDFEM0E5RkQ1NEZCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOkYzNkFCQ0ZCMTBCRTExRTM5NDk4RDFEM0E5RkQ1NEZCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6RjM2QUJDRjgxMEJFMTFFMzk0OThEMUQzQTlGRDU0RkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6RjM2QUJDRjkxMEJFMTFFMzk0OThEMUQzQTlGRDU0RkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz7h1bLqAAAAWUlEQVR42mL8////BwYGBn4GCACxBRlIAIxAA/4jaXoPEkMyjJ+A/g9MDJQBRhYg8RFqMwg8RJIUINYLFDmBUi+ADQAF1n8ofk9yIAy6WPg4GgtDMRYAAgwAdLYwLAoIwPgAAAAASUVORK5CYII=);
}

.bar a.grid-icon {
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjBEQkMyQzE0MTBCRjExRTNBMDlGRTYyOTlBNDdCN0I4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjBEQkMyQzE1MTBCRjExRTNBMDlGRTYyOTlBNDdCN0I4Ij4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MERCQzJDMTIxMEJGMTFFM0EwOUZFNjI5OUE0N0I3QjgiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6MERCQzJDMTMxMEJGMTFFM0EwOUZFNjI5OUE0N0I3QjgiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz4MjPshAAAAXklEQVR42mL4////h/8I8B6IGaCYKHFGEMnAwCDIAAHvgZgRyiZKnImBQsACxB+hNoDAQyQ5osQZIT4gH1DsBZABH6AB8x/JaQzEig++WPiII7Rxio/GwmCIBYAAAwAwVIzMp1R0aQAAAABJRU5ErkJggg==);
}
/*-------------------------
  List layout
--------------------------*/

ul.list {
  list-style: none;
  width: 500px;
  margin: 0 auto;
  text-align: left;
}

ul.list li {
  border-bottom: 1px solid #ddd;
  padding: 10px;
  overflow: hidden;
}

ul.list li img {
  width: 120px;
  height: 120px;
  float: left;
  border: none;
}

ul.list li p {
  margin-left: 135px;
  font-weight: bold;
  color: #6e7a7f;
}
/*-------------------------
  Grid layout
--------------------------*/

ul.grid {
  list-style: none;
  width: 570px;
  margin: 0 auto;
  text-align: left;
}

ul.grid li {
  padding: 2px;
  float: left;
}

ul.grid li img {
  width: 280px;
  height: 280px;
  display: block;
  border: none;
}
于 2016-06-18T21:48:27.047 回答
3

这是一个简单的工作 JSBin:http: //jsbin.com/jomiquqi/1/edit

ng-include指令需要一个变量供模板包含。因此,要更新您的代码以使其正常工作,您的toggleGrid()方法不应返回某些内容,它应该在您传递给的范围内设置一个变量,ng-include就像我的示例中一样。

于 2014-03-17T06:47:07.247 回答
1

为了更好地理解切换操作以查看列表和网格视图: 点击此链接,我希望这会有所帮助。

如果您正在对此进行试验,我们在此使用了 Jquery。做这个: <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

于 2017-02-17T11:07:57.257 回答
0

一个简单的轻量级解决方案,它是使用AngularJS Material没有任何指令的库构建的。当用户单击listView时,容器的布局变为column不换行,当用户单击时gridView,它变为row带换行。

'use strict';
const application = angular.module("application", ['ngMaterial']);
application.controller('applicationCtrl', ['$scope', function(scope) {
  scope.toggleGridList = function(newValue) {
    if (newValue === "gridView") {
      scope.value = 'gridView';
      scope.layout = 'row';
    } else {
      scope.value = 'listView';
      scope.layout = 'column';
    }
  };
  scope.onInit = function() {
    scope.toggleGridList('listView');
  };
}]);
.grid-list-toggle {
  padding: 0 !important;
  margin: 8px;
  border-radius: 2px;
  border: 1px solid #c8e6c9;
}

.grid-list-button {
  margin: 0 !important;
  min-width: 0 !important;
  min-height: 0 !important;
  border-radius: 0 !important;
}

.grid-list-button.selected {
  background-color: #c8e6c9;
}
<head>
  <link rel="stylesheet" href="https://material.angularjs.org/1.1.24/angular-material.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.8.0/angular.min.js"></script>
  <script src="https://code.angularjs.org/1.8.0/angular-animate.min.js"></script>
  <script src="https://code.angularjs.org/1.8.0/angular-aria.min.js"></script>
  <script src="https://material.angularjs.org/1.1.24/angular-material.min.js"></script>
</head>

<body ng-app="application" ng-controller="applicationCtrl"
      ng-init="onInit();" class="ng-cloak" style="overflow: hidden;">
  <!-- Header -->
  <div layout="row" md-whiteframe="1" layout-align="start center">
    <!-- Title -->
    <div layout-padding>
      <span class="md-display-1" style="color: #1b5e20;">Grid-list toggle button</span>
    </div>
    <!-- Divider -->
    <div flex></div>
    <!-- Grid-list toggle button -->
    <div layout="row" layout-padding class="grid-list-toggle">
      <md-button class="grid-list-button" ng-click="toggleGridList('listView')"
          aria-label="List" ng-class="value == 'listView' ? 'selected' : ''">
        <div style="height: 30px">
          <img src="https://i.stack.imgur.com/SOqYv.png">
        </div>
      </md-button>
      <md-button class="grid-list-button" ng-click="toggleGridList('gridView')"
          aria-label="Grid" ng-class="value == 'gridView' ? 'selected' : ''">
        <div style="height: 30px">
          <img src="https://i.stack.imgur.com/STQJn.png">
        </div>
      </md-button>
    </div>
  </div>
  <!-- Page content -->
  <div flex="100" layout="column" md-whiteframe="1">
    <div layout="{{layout}}" layout-padding style="overflow-y: auto;"
        ng-class="value == 'gridView' ? 'layout-wrap' : 'layout-nowrap'">
      <div layout="row" layout-padding layout-align="start center" class="grid-list-toggle"
          ng-repeat="number in [].constructor(10) track by $index">
        <img src="https://i.stack.imgur.com/WANVK.png">
        <div layout="column">
          <span>Title {{$index}}</span>
          <span>Description</span>
          <span>Another line</span>
        </div>
      </div>
    </div>
  </div>
</body>


请参阅:《网格列表切换按钮》。

于 2020-08-21T19:37:52.937 回答