- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我很好奇这是否可能在 Ember 中。这在 Angular 中很容易做到( plunkr: http://plnkr.co/edit/O2e0ukyXdKMs4FcgKGmX?p=preview ):
目标是为 api 消费者制作一个易于使用、通用、可重复使用的 Accordion api。
我希望调用者能够使用的 api 是这样的(就像 angular api 一样):
{{#ember-accordion listOfAccordionPaneObjects=model}}
{{#ember-accordion-heading}}
heading template html {{accordionPaneObject.firstName}}
{{/ember-accordion-heading}}
{{#ember-accordion-body}}
this is the accordion body {{accordionPaneObject.lastName}}
{{/ember-accordion-body}}
{{/ember-accordion}}
<!doctype html>
<html ng-app="angular-accordion">
<head>
<style>
.angular-accordion-header {
background-color: #999;
color: #ffffff;
padding: 10px;
margin: 0;
line-height: 14px;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
cursor: pointer;
text-decoration: none;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
}
.angular-accordion-container {
height: 100%;
width: 100%;
}
.angular-accordion-pane {
padding: 2px;
}
.angularaccordionheaderselected {
background-color: #bbb;
color: #333;
font-weight: bold;
}
.angular-accordion-header:hover {
text-decoration: underline !important;
}
.angularaccordionheaderselected:hover {
text-decoration: underline !important;
}
.angular-accordion-pane-content {
padding: 5px;
overflow-y: auto;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-bottom: 1px solid #bbb;
-webkit-border-bottom-left-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomleft: 5px;
-moz-border-radius-bottomright: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.angulardisabledpane {
opacity: .2;
}
</style>
</head>
<body style="margin: 0;">
<div style="height: 90%; width: 100%; margin: 0;" ng-controller="outerController">
<angular-accordion list-of-accordion-pane-objects="outerControllerData">
<pane>
<pane-header>Header {{accordionPaneObject}}</pane-header>
<pane-content>Content {{accordionPaneObject}}</pane-content>
</pane>
</angular-accordion>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.1/angular.js"></script>
<script>
angular.module('angular-accordion', [])
.directive('angularAccordion', function() {
var template = '';
return {
restrict: 'E',
transclude: true,
replace: true,
template: '<div>' +
'<div ng-transclude class="angular-accordion-container" ng-repeat="accordionPaneObject in listOfAccordionPaneObjects"></div>' +
'</div>',
controller: ['$scope', function($scope) {
var panes = [];
this.addPane = function(pane) {
panes.push(pane);
};
}],
scope: {
listOfAccordionPaneObjects: '='
}
};
})
.directive('pane', function() {
return {
restrict: 'E',
transclude: true,
replace: true,
template: '<div ng-transclude class="angular-accordion-pane"></div>'
};
})
.directive('paneHeader', function() {
return {
restrict: 'E',
require: '^angularAccordion',
transclude: true,
replace: true,
link: function(scope, iElement, iAttrs, controller) {
controller.addPane(scope);
scope.toggle = function() {
scope.expanded = !scope.expanded;
};
},
template: '<div ng-transclude class="angular-accordion-header" ng-click="toggle()"></div>'
};
})
.directive('paneContent', function() {
return {
restrict: 'EA',
require: '^paneHeader',
transclude: true,
replace: true,
template: '<div ng-transclude class="angular-accordion-pane-content" ng-show="expanded"></div>'
};
})
.controller('outerController', ['$scope', function($scope) {
$scope.outerControllerData = [1, 2, 3];
}]);
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<body>
<script src="//cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.js" data-main="main.js"></script>
</body>
</html>
require.config({
paths: {
'ember': 'bower_components/ember/ember',
'handlebars': 'bower_components/handlebars/handlebars',
'jquery': 'bower_components/jquery/jquery',
'text': 'bower_components/requirejs-text/text'
},
shim: {
ember: {
deps: ['jquery', 'handlebars'],
exports: 'Ember'
}
}
});
define(function(require) {
var Ember = require('ember'),
EmberAccordionComponent = require('src/EmberAccordionComponent'),
EmberAccordionTemplate = require('text!templates/ember-accordion.hbs'),
EmberAccordionHeaderTemplate = require('text!templates/ember-accordion-header.hbs'),
EmberAccordionBodyTemplate = require('text!templates/ember-accordion-body.hbs'),
ApplicationTemplate = require('text!templates/application.hbs'),
IndexTemplate = require('text!templates/index.hbs');
var App = Ember.Application.create({
LOG_STACKTRACE_ON_DEPRECATION : true,
LOG_BINDINGS : true,
LOG_TRANSITIONS : true,
LOG_TRANSITIONS_INTERNAL : true,
LOG_VIEW_LOOKUPS : true,
LOG_ACTIVE_GENERATION : true
});
Ember.TEMPLATES = {};
Ember.TEMPLATES['application'] = Ember.Handlebars.compile(ApplicationTemplate);
Ember.TEMPLATES['index'] = Ember.Handlebars.compile(IndexTemplate);
Ember.TEMPLATES['components/ember-accordion'] = Ember.Handlebars.compile(EmberAccordionTemplate);
Ember.TEMPLATES['components/ember-accordion-header'] = Ember.Handlebars.compile(EmberAccordionHeaderTemplate);
Ember.TEMPLATES['components/ember-accordion-body'] = Ember.Handlebars.compile(EmberAccordionBodyTemplate);
App.EmberAccordionComponent = EmberAccordionComponent;
App.IndexRoute = Ember.Route.extend({
model: function() {
return [
{
name: 'Bob'
},
{
name: 'Jill'
}]
}
})
});
define(function(require) {
require('ember');
var EmberAccordionComponent = Ember.Component.extend({});
return EmberAccordionComponent;
});
{{outlet}}
<div style="color: blue;">
{{yield}}
</div>
<div style="color: green;">
{{yield}}
</div>
{{#ember-accordion listOfAccordionPaneObjects=model}}
{{#ember-accordion-header}}
{{log this.constructor}}
{{log this}}
Header {{accordionPaneObject.name}}
{{/ember-accordion-header}}
{{#ember-accordion-body}}
Body {{accordionPaneObject.name}}
{{/ember-accordion-body}}
{{/ember-accordion}}
{{#each accordionPaneObject in listOfAccordionPaneObjects}}
{{yield}}
{{/each}}
{{log this.constructor}}
{{log this}}
{{#ember-accordion-header}}
var EmberAccordionHeaderComponent = Ember.Component.extend({
_yield: function(context, options) {
var get = Ember.get,
view = options.data.view,
parentView = this._parentView,
template = get(this, 'template');
if (template) {
Ember.assert("A Component must have a parent view in order to yield.", parentView);
view.appendChild(Ember.View, {
isVirtual: true,
tagName: '',
_contextView: parentView,
template: template,
context: get(view, 'context'), // the default is get(parentView, 'context'),
controller: get(view, 'controller'), // the default is get(parentView, 'context'),
templateData: { keywords: parentView.cloneKeywords() }
});
}
}
});
var EmberAccordionHeaderComponent = Ember.Component.extend({
_yield: function(context, options) {
var get = Ember.get,
view = options.data.view,
parentView = this._parentView,
grandParentView = this._parentView._parentView,
template = get(this, 'template');
if (template) {
Ember.assert("A Component must have a parent view in order to yield.", parentView);
view.appendChild(Ember.View, {
isVirtual: true,
tagName: '',
_contextView: parentView,
template: template,
context: get(grandParentView, 'context'), // the default is get(parentView, 'context'),
controller: get(grandParentView, 'controller'), // the default is get(parentView, 'context'),
templateData: { keywords: parentView.cloneKeywords() }
});
}
}
});
this._parentView._context.content
最佳答案
我用一些评论更新了你的代码,请看一下 http://emberjs.jsbin.com/ivOyiZa/1/edit .
Javascript
App = Ember.Application.create();
App.IndexRoute = Ember.Route.extend({
model: function() {
return [
{ head: "foo head", body: "foo body " },
{ head: "bar head", body: "bar body " },
{ head: "ya head", body: "yo body " }
];
}
});
App.EmberAccordionComponent = Ember.Component.extend({
// each accordion header/body item, will have a instance of that view.
// so we can isolate the expanded state for each accordion header/body
emberAccordionItemView: Ember.View.extend({
expanded: false
}),
_yield: function(context, options) {
var get = Ember.get,
view = options.data.view,
parentView = this._parentView,
template = get(this, 'template');
if (template) {
Ember.assert("A Component must have a parent view in order to yield.", parentView);
view.appendChild(Ember.View, {
isVirtual: true,
tagName: '',
_contextView: parentView,
template: template,
context: get(view, 'context'), // the default is get(parentView, 'context'),
controller: get(view, 'controller'), // the default is get(parentView, 'context'),
templateData: { keywords: parentView.cloneKeywords() }
});
}
}
});
App.EmberAccordionHeaderComponent = Ember.Component.extend({
classNames: ['ember-accordion-header'],
click: function() {
// here we toggle the emberAccordionItemView.expanded property
this.toggleProperty('parentView.expanded');
}
});
<script type="text/x-handlebars" data-template-name="index">
{{#ember-accordion listOfAccordionPaneObjects=model}}
{{#ember-accordion-header}}
{{head}} <!-- each object passed in listOfAccordionPaneObjects=model can be accessed here -->
{{/ember-accordion-header}}
{{#ember-accordion-body}}
{{body}} <!-- each object passed in listOfAccordionPaneObjects=model can be accessed here -->
{{/ember-accordion-body}}
{{/ember-accordion}}
</script>
<script type="text/x-handlebars" data-template-name="components/ember-accordion">
{{#each listOfAccordionPaneObjects itemViewClass="view.emberAccordionItemView"}}
<div class="ember-accordion-container">
<div class="ember-accordion-pane">
{{yield}}
</div>
</div>
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="components/ember-accordion-header">
{{yield}}
</script>
<script type="text/x-handlebars" data-template-name="components/ember-accordion-body">
<!-- when EmberAccordionHeaderComponent.click is called, the expanded property change and the content can be visible or not, based on expanded truth -->
{{#if parentView.expanded}}
<div class="ember-accordion-pane-content">
{{yield}}
</div>
{{/if}}
</script>
.ember-accordion-header {
background-color: #999;
color: #ffffff;
padding: 10px;
margin: 0;
line-height: 14px;
-webkit-border-top-left-radius: 5px;
-webkit-border-top-right-radius: 5px;
-moz-border-radius-topleft: 5px;
-moz-border-radius-topright: 5px;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
cursor: pointer;
text-decoration: none;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
}
.ember-accordion-container {
height: 100%;
width: 100%;
}
.ember-accordion-pane {
padding: 2px;
}
.emberaccordionheaderselected {
background-color: #bbb;
color: #333;
font-weight: bold;
}
.ember-accordion-header:hover {
text-decoration: underline !important;
}
.emberaccordionheaderselected:hover {
text-decoration: underline !important;
}
.ember-accordion-pane-content {
padding: 5px;
overflow-y: auto;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-bottom: 1px solid #bbb;
-webkit-border-bottom-left-radius: 5px;
-webkit-border-bottom-right-radius: 5px;
-moz-border-radius-bottomleft: 5px;
-moz-border-radius-bottomright: 5px;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
}
.emberdisabledpane {
opacity: .2;
}
关于api - 如何从 ember 中的子组件范围访问父组件范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20158948/
我有这个 html 代码: HELLO WORLD! X V HELLO WORLD! X V 我想按 X(类关闭)将父 div 的高度更改为 20px 并显示 V(类打开),但在每个 d
在会计应用程序的许多不同实现中,有两种主要的数据库设计方法来保存日志和分类帐数据。 只保留 Journal 信息,然后 Ledger 只是 Journal 的一个 View (因为 journal 总
我想在另一个子里面有一个子, sub a { sub b { } } 我想为每次调用 sub b 创建一个新的 sub a 实例。有没有办法在 Perl 中做到这一点? 当我运行上面的
我有一些代码正在查找重复项并突出显示单元格: Private Sub cmdDups_Click() Dim Rng As Range Dim cel As Range Set Rng = ThisW
可能有一个简单的解决方案,但我很难过。 我有一个包含一个 ID 字段的主表。在两个可能的字段中有一个具有该 ID 的子表。想象一个由选手 A 和选手 B 组成的 double 队。Master 表将有
假设我有一个包含对象的数组: [ { "id": "5a97e047f826a0111b754beb", "name": "Hogwarts", "parentId": "
我正在尝试对 MySQL 数据库表执行一对父/子模型的批量插入,但似乎无法使用标准的 ActiveRecord 功能来完成。所以,我尝试了 activerecord-import gem,但它也不支持
我有一个带有多个子类的父抽象类。最终,我希望通过 GUI 中的进度条显示子类中完成的进度。 我目前所做的,我意识到这是行不通的,是在父类中声明为每个子类将覆盖的虚拟方法的事件方法定义。所以像: pub
是否可以通过键数组在对象中设置变量?例如我有这个对象: var obj = {'outer': {'inner': 'value'} }; 并希望设置由键数组选择的值: var keys = ['ou
我有一个名为 companies 的 MySQL 表,如下所示: +---------+-----------+-----------+ | id_comp | comp_name | id_pare
我正在尝试使用 sublime text 在 sublime text 上的 ionic 上打开我的第一个应用程序。它给了我一个“找不到命令”的错误。如何修复? 我试过这些命令: sudo rm -r
不好意思问,但我正在使用 webapp2,我正在设计一个解决方案,以便更容易定义路由 based on this google webapp2 route function .但这完全取决于能够在子级
我有代表树的数字字符串(我不知道是否有官方名称): 012323301212 上面的例子代表了 2 棵树。根用 0 表示。根的直接子代为“1”,“1”的直接子代为“2”,依此类推。我需要将它们分组到由
是否可以在当前 Activity 之上添加 Activity 。例如,假设我单击一个按钮,然后它将第二个 Activity 添加到当前 Activity 。而第二个 Activity 只覆盖了我当前
我很难思考如何为子资源建模。 以作者的书籍为例。你可以有 N 本书,每本书只有一位作者。 /books GET /books POST /books/id PUT /books/id DELETE 到
有人可以向我解释以下内容(python 2.7) 来自已解析文件的两个字符串数字: '410.9''410.9 '(注意尾随空格) A_LIST = ['410.9 '] '410.9' in '41
背景 在 PowerShell 中构建 hash table 是很常见的通过特定属性快速访问对象,例如以 LastName 为基础建立索引: $List = ConvertFrom-Csv @' I
我真的很难弄清楚如何调用嵌套 Polymer Web 组件的函数。 这是标记: rise-distribution组件有 canPlay我想从 rise-playlist
我写了一个小工具转储(以 dot 格式)一个项目的依赖关系图,其中所有位于同一目录中的文件都聚集在一个集群中。当我尝试生成包含相应图形的 pdf 时,dot开始哭: 命令 dot -Tpdf trim
给定一个 CODE ref,是否可以: 访问该 CODE ref 的解析树 通过指定 CODE ref 的解析树来创建一个新的 CODE ref,该解析树可以包含在 1 中返回的解析树的元素 通常我们
我是一名优秀的程序员,十分优秀!