Meteor、Iron Router 和 Google 分析嵌入 API
Meteor, Iron Router, & Google Analytics Embed API
在尝试通过 Meteor 的 accounts-google
包对 Google API 调用进行身份验证后,我决定尝试使用 Analytics 的 Embed API 来降低一些复杂性。我已经能够通过在每个模板上加载客户端库、进行身份验证等来使各个仪表板正常工作,但这当然效率低下并且充满了重复。
加载 Embed API 库、身份验证和视图选择器一次,同时允许模板在使用 Iron Router 加载时检测它们的最佳方法是什么?还是我只是强迫 Meteor 进入它不适合的应用程序?
我添加了一些示例代码来了解现在的结构:
/client/layout.html
<template name="layout">
<header>
<h1><a href="{{pathFor 'basic'}}">DDDashboard</a></h1>
</header>
<section id="admin">
<div id="auth-button"></div> <!-- Outlet for Embed API's auth -->
{{> view}} <!-- Outlet for the View template -->
</section>
<section id="main">
{{> yield}} <!-- Outlet for each dashboard -->
</section>
</template>
/client/view.html
此模板用于 Template.foo.rendered
以防止在嵌入 API 视图选择器完全实例化之前加载仪表板。
<template name="view">
<div id="view-selector"></div>
</template>
/client/basic.html
仪表板的一般示例 - 嵌入 API 依赖于预定义的元素来呈现。更复杂的仪表板将有更多 <div>
来包含其他 charts/info.
<template name="basic">
<div id="data-container"></div> <!-- Outlet for the Embed API chart -->
</template>
/lib/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {
name: 'basic'
});
/client/lib/gapi.js
在启动时加载 Google 嵌入 API 库。
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
/client/auth.js
gapi.analytics.ready(function(){
gapi.analytics.auth.authorize({
container: 'auth-button',
clientid: 'INSERT-CLIENTID'
});
});
/client/view.js
嵌入 API 库完全加载后,视图选择器将创建为全局变量,因此任何图表或数据对象都可以访问它。
gapi.analytics.ready(function(){
viewSelector = new gapi.analytics.ViewSelector({
container: 'view-selector'
});
viewSelector.execute();
});
/client/basic.js
使用Template.foo.rendered
等待视图选择器加载;如果不是,则图表 div
保持为空。该仪表板包含一个图表;其他人会包含许多但或多或少相同的模式。
Template.view.rendered = function(){
gapi.analytics.ready(function(){
var dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
metrics: 'ga:sessions',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'data-container',
type: 'LINE',
options: {
width: '100%'
}
}
});
viewSelector.on('change', function(ids){
dataChart.set({query: {ids: ids}}).execute();
});
});
};
事实证明非常简单——只需要添加一些 Meteor 糖就可以让事情正常运行。简单解释:在 viewSelector 发生变化时,将当前视图设置为 Session 变量;然后添加 Tracker.autorun()
块以获取更新并让图表自行更新。此外,积极使用 Template.view.created
回调以确保对象以正确的顺序加载并且不会被多次渲染。
/client/view.js
Template.view.created = function(){
gapi.analytics.ready(function(){
var viewSelector = new gapi.analytics.ViewSelector({
container: 'view-selector'
});
viewSelector.execute();
viewSelector.on('change', function(ids){
Session.set('currentView', ids);
});
});
};
/client/basic.js
Template.users.created = function(){
gapi.analytics.ready(function(){
dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
metrics: 'ga:users',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'data-container',
type: 'LINE',
options: {
width: '100%'
}
}
});
Tracker.autorun(function(){
if(Session.get('currentView')){
dataChart.set({query: {ids: Session.get('currentView')}}).execute();
}
});
});
};
我确信这种模式还有改进的余地——将每个会话变量包装到每个仪表板上的 Tracker.autorun()
块中似乎有点多余,但将所有选择器和数据对象保持在本地范围内可能是a 但更安全,更能抵抗用户篡改。也适用于日期选择。
在尝试通过 Meteor 的 accounts-google
包对 Google API 调用进行身份验证后,我决定尝试使用 Analytics 的 Embed API 来降低一些复杂性。我已经能够通过在每个模板上加载客户端库、进行身份验证等来使各个仪表板正常工作,但这当然效率低下并且充满了重复。
加载 Embed API 库、身份验证和视图选择器一次,同时允许模板在使用 Iron Router 加载时检测它们的最佳方法是什么?还是我只是强迫 Meteor 进入它不适合的应用程序?
我添加了一些示例代码来了解现在的结构:
/client/layout.html
<template name="layout">
<header>
<h1><a href="{{pathFor 'basic'}}">DDDashboard</a></h1>
</header>
<section id="admin">
<div id="auth-button"></div> <!-- Outlet for Embed API's auth -->
{{> view}} <!-- Outlet for the View template -->
</section>
<section id="main">
{{> yield}} <!-- Outlet for each dashboard -->
</section>
</template>
/client/view.html
此模板用于 Template.foo.rendered
以防止在嵌入 API 视图选择器完全实例化之前加载仪表板。
<template name="view">
<div id="view-selector"></div>
</template>
/client/basic.html
仪表板的一般示例 - 嵌入 API 依赖于预定义的元素来呈现。更复杂的仪表板将有更多 <div>
来包含其他 charts/info.
<template name="basic">
<div id="data-container"></div> <!-- Outlet for the Embed API chart -->
</template>
/lib/router.js
Router.configure({
layoutTemplate: 'layout'
});
Router.route('/', {
name: 'basic'
});
/client/lib/gapi.js
在启动时加载 Google 嵌入 API 库。
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
/client/auth.js
gapi.analytics.ready(function(){
gapi.analytics.auth.authorize({
container: 'auth-button',
clientid: 'INSERT-CLIENTID'
});
});
/client/view.js
嵌入 API 库完全加载后,视图选择器将创建为全局变量,因此任何图表或数据对象都可以访问它。
gapi.analytics.ready(function(){
viewSelector = new gapi.analytics.ViewSelector({
container: 'view-selector'
});
viewSelector.execute();
});
/client/basic.js
使用Template.foo.rendered
等待视图选择器加载;如果不是,则图表 div
保持为空。该仪表板包含一个图表;其他人会包含许多但或多或少相同的模式。
Template.view.rendered = function(){
gapi.analytics.ready(function(){
var dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
metrics: 'ga:sessions',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'data-container',
type: 'LINE',
options: {
width: '100%'
}
}
});
viewSelector.on('change', function(ids){
dataChart.set({query: {ids: ids}}).execute();
});
});
};
事实证明非常简单——只需要添加一些 Meteor 糖就可以让事情正常运行。简单解释:在 viewSelector 发生变化时,将当前视图设置为 Session 变量;然后添加 Tracker.autorun()
块以获取更新并让图表自行更新。此外,积极使用 Template.view.created
回调以确保对象以正确的顺序加载并且不会被多次渲染。
/client/view.js
Template.view.created = function(){
gapi.analytics.ready(function(){
var viewSelector = new gapi.analytics.ViewSelector({
container: 'view-selector'
});
viewSelector.execute();
viewSelector.on('change', function(ids){
Session.set('currentView', ids);
});
});
};
/client/basic.js
Template.users.created = function(){
gapi.analytics.ready(function(){
dataChart = new gapi.analytics.googleCharts.DataChart({
query: {
metrics: 'ga:users',
dimensions: 'ga:date',
'start-date': '30daysAgo',
'end-date': 'yesterday'
},
chart: {
container: 'data-container',
type: 'LINE',
options: {
width: '100%'
}
}
});
Tracker.autorun(function(){
if(Session.get('currentView')){
dataChart.set({query: {ids: Session.get('currentView')}}).execute();
}
});
});
};
我确信这种模式还有改进的余地——将每个会话变量包装到每个仪表板上的 Tracker.autorun()
块中似乎有点多余,但将所有选择器和数据对象保持在本地范围内可能是a 但更安全,更能抵抗用户篡改。也适用于日期选择。