如何从ember中的子组件范围访问父组件范围? [英] how to access parent component scope from a child components scope in ember?
问题描述
目标是为api消费者制作一个易于使用,通用,可重复使用的手风琴api。
我想让呼叫者能够使用的是这个(就像角api):
{{ember-accordion listOfAccordionPaneObjects = model}}
{{ember-accordion-heading}}
标题模板html {{accordionPaneObject.firstName}}
{{/ ember-accordion-heading}}
{{ember-accordion-body}}
这是手风琴本体{{accordionPaneObject.lastName}}
{ {/ ember-accordion-body}}
{{/ ember-accordion}}
这是一个使用角度写的工作示例:
<!doctype html>
< html ng-app =角度手风琴>
< head>
< style>
.angular-accordion-header {
background-color:#999;
颜色:#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;
颜色:#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-控制器= outerController >
< angle-accordion list-of-accordion-pane-objects =outerControllerData>
< pane>
< pane-header>标题{{accordionPaneObject}}< / pane-header>
< pane-content> Content {{accordionPaneObject}}< / pane-content>
< / pane>
< /角度手风琴>
< / 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>'+
'< divng -transclude class =angular-accordion-containerng-repeat =listOfAccordionPaneObjects中的accordionPaneObject>< / div>'+
'< / div>',
controller:['$范围',function($ scope){
var panes = [];
this.addPane = function(pane){
panes.push(pane);
};
}],
范围:{
listOfAccordionPaneObjects:'='
}
};
})
.directive('pane',function(){
return {
restrict:'E',
transclude:true,
replace :true,
template:'< divng-transclude class =angular-accordion-pane>< / div>'
};
})
。指令('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:'< divng-transclude class =angular-accordion-headerng-click =toggle()>< / div>'
} ;
})
.directive('paneContent',function(){
return {
restrict:'EA',
require:'^ paneHeader',
transclude:true,
replace:true,
template:'< divng-transclude class =angular-accordion-pane-contentng-show =expanded>< / ($ scope),$($ scope){
$ scope.outerControllerData = [1, 2,3];
}]);
< / script>
< / body>
< / html>
这里是我与ember做同样的事情:
index.html
<!DOCTYPE html>
< html>
< body>
< script src =// cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.jsdata-main =main.js>< / script>
< / body>
< / html>
main.js
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 / bbbb / b / b / bin / html);
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.TEMP LATES = {};
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'
}]
}
})
});
EmberAccordionComponent.js
define(function(require){
require('ember');
var EmberAccordionComponent = Ember.Component.extend({});
return EmberAccordionComponent;
});
application.hbs
{{outlet}}
ember-accordion-header.hbs
< div style =color:blue;>
{{yield}}
< / div>
ember-accordion-body.hbs
< div style =color:green;>
{{yield}}
< / div>
index.hbs
{{#ember-accordion listOfAccordionPaneObjects = model}}
{{ember-accordion-header}}
{{log this.constructor}}
{{log这个}}
标题{{accordionPaneObject.name}}
{{/ ember-accordion-header}}
{{ember-accordion-body}}
Body { accordionPaneObject.name}}
{{/ ember-accordion-body}}
{{/ ember-accordion}}
ember-accordion.hbs
{{#listOfAccordionPaneObjects中的每个accordionPaneObject}}
{{yield}}
{{/ each}}
-
这是很难调试的。所以放入:
{{log this.constructor}}
pre>
和:
{{log this}}
到:
code> {{#ember-accordion-header}}
输出以下内容: p>
- Class.model = undefined(为什么?)
- Ember.ArrayController
我已经尝试覆盖了本文所建议的Ember.Component的私有_yield方法( http://www.thesoftwaresimpleton.com/blog/2013/11/21/component-block/ ):
var EmberAccordionHeaderComponent = Ember.Component.extend({
_yield:function(context,options){
var get = Ember.get,
view = options.data.view,
parentView = this._parentView,
template = get (这个,'模板');
if(template){
Ember.assert(A Component must have a parent view for to yield。,parentView);
view.appendChild(Ember.View,{
isVirtual:true,
tagName:'',
_contextView:parentView,
template:template,
上下文:get(view,'context'),//默认为get(parentView,'context'),
controller:get(view,'controller'),//默认为get(parentView,上下文),
templateData:{keywords:parentView.cloneKeywords()}
});
}
}
});
但是当我这样做时,我仍然无法访问我的子组件范围中的accordionPaneObject,我的{{log this.constructor}}现在指向:.EmberAccordionHeaderComponent
所以看起来我正在某个地方,我只需要再一个级别。
当我尝试在EmberAccordionHeaderComponent.js中使用此代码时:
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必须有父视图才能产生,parentView);
view.appendChild(Ember.View,{
isVirtual:true,
tagName:'',
_contextView:parentView,
template:template,
context:get(grandParentView,'context'),//默认是get(parentView,'context'
控制器:get(grandParentView,'controller'),//默认为get(parentView,'context'),
templateData:{keywords:parentView.cloneKeywords()}
}) ;
}
}
});
我还没有访问accordionPaneObject,但现在我看到{{log this.constructor} }输出.EmberAccordionComponent。所以看来我是在正确的范围,但数据仍然没有绑定。
有趣的是,如果我使用任何这些变体重新分配上下文和控制器在我覆盖的_yield中,我可以使用以下方式访问控制台中的数据:
this._parentView._context.content
我用一些评论更新了你的代码, a href =http://emberjs.jsbin.com/ivOyiZa/1/edit> 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({
//每个手风琴头/主体项目,将具有该视图的一个实例
//所以我们可以隔离每个手风琴头/ 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 for to yield。,parentView);
view.appendChild(Ember.View,{
isVirtual:true,
tagName:'',
_contextView:parentView,
template:template,
context:get(view,'context'),//默认是get(parentView,'context'),
controller:get(view,'controller'),//默认是get(parentView ,'context'),
templateData:{keywords:parentView.cloneKeywords()}
});
}
}
});
App.EmberAccordionHeaderComponent = Ember.Component.extend({
classNames:['ember-accordion-header'],
click:function(){
/ /这里我们切换emberAccordionItemView.expanded属性
this.toggleProperty('parentView.expanded');
}
});
模板
< script type =text / x-handlebarsdata-template-name =index>
{{ember-accordion listOfAccordionPaneObjects = model}}
{{ember-accordion-header}}
{{head}}<! - 在listOfAccordionPaneObjects =模型中传递的每个对象可以在这里访问 - >
{{/ ember-accordion-header}}
{{ember-accordion-body}}
{{body}}<! - 在listOfAccordionPaneObjects =模型中传递的每个对象在这里访问 - >
{{/ ember-accordion-body}}
{{/ ember-accordion}}
< / script>
< script type =text / x-handlebarsdata-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-handlebarsdata-template-name =components / ember-accordion-header>
{{yield}}
< / script>
< script type =text / x-handlebarsdata-template-name =components / ember-accordion-body>
<! - 当EmberAccordionHeaderComponent.click被调用时,扩展的属性更改和内容可以根据扩展的真值可见或不可见 - >
{{#if parentView.expanded}}
< div class =ember-accordion-pane-content>
{{yield}}
< / div>
{{/ if}}
< / script>
Css
.ember-accordion-header {
background-color:#999;
颜色:#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;
颜色:#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;
}
I'm curious if this is even possible in ember. This is an easy thing to do in angular ( plunkr: http://plnkr.co/edit/O2e0ukyXdKMs4FcgKGmX?p=preview ):
The goal is to make an easy to use, generic, reusable accordion api for api consumers.
The api I want the caller to be able to use is this (just like the 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}}
Here is a working example I wrote using angular:
<!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>
here's where I'm stuck doing the same with ember:
index.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>
main.js
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'
}]
}
})
});
EmberAccordionComponent.js
define(function(require) {
require('ember');
var EmberAccordionComponent = Ember.Component.extend({});
return EmberAccordionComponent;
});
application.hbs
{{outlet}}
ember-accordion-header.hbs
<div style="color: blue;">
{{yield}}
</div>
ember-accordion-body.hbs
<div style="color: green;">
{{yield}}
</div>
index.hbs
{{#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}}
ember-accordion.hbs
{{#each accordionPaneObject in listOfAccordionPaneObjects}}
{{yield}}
{{/each}}
--
This is tricky to debug. So putting in the:
{{log this.constructor}}
and the:
{{log this}}
into the:
{{#ember-accordion-header}}
outputs the following:
- Class.model = undefined (why?)
- Ember.ArrayController
I've tried overriding the private _yield method of Ember.Component as suggested by this article ( http://www.thesoftwaresimpleton.com/blog/2013/11/21/component-block/ ):
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() }
});
}
}
});
but when I do this I still don't have access to accordionPaneObject in my child component scope, and my {{log this.constructor}} now points to: .EmberAccordionHeaderComponent
So it looks like I'm getting somewhere, I just need to go one more level up.
When I try that using this code in EmberAccordionHeaderComponent.js:
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() }
});
}
}
});
I still don't access to accordionPaneObject in, but now I see {{log this.constructor}} outputting .EmberAccordionComponent. So it appears I'm in the right scope, but the data still doesn't bind.
Interestingly enough, if I use any of these variations of reassigning context and controller in my overridden _yield, I can access the data I am after in the console using:
this._parentView._context.content
I updated your code with some comments please give a look 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');
}
});
Templates
<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>
Css
.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;
}
这篇关于如何从ember中的子组件范围访问父组件范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!