angular 路由解析 - 等待定义值
angular route resolve - wait on value to be defined
我有条件地为 load/unload javascript 和 css 写了一个包装器。它在路由解析部分被称为:
resolve: {
factory: function (Res) {
controllersAndServices(Res, {styles: 'estilos/check_insurance.css'})
}
}
它通常很有魅力。问题是,一些库,比如 Plotly 推迟创建它们的主变量,所以库在可用之前加载。结果,我收到 Plotly 未在我的控制器中定义的错误,然后它们消失了。 肯定 当我到达控制台时,Plotly 正在愉快地等着我。
我确实意识到我的自定义加载器可能会在更多的库中发生这种情况,但令人高兴的是,大多数库都太小而不会出现这个问题。 plotly 很大,可能需要数百甚至数千毫秒才能设置。
所以我需要等待 Plotly 在我的 resolve
中以某种方式被定义。你是怎么做到的?
图书馆:
res_service.js
angular.module('app').service('Res', ['$rootScope', function ($rootScope) {
var scope = $rootScope
scope._scripts = scope._scripts || []
scope._styles = scope._styles || []
scope._rawScripts = scope._rawScripts || []
scope._rawStyles = scope._rawStyles || []
return {
style: function (inp) {
var hrefs = []
if (typeof inp === 'string') {
hrefs.push(inp)
} else {
hrefs = inp
}
scope._styles = []
for (var i in hrefs) {
console.log('styling page with ' + hrefs[i])
var style = document.createElement('link')
if (!/^https?\:\/\//.test(hrefs[i])) {
style.type = 'text/css'
}
style.href = hrefs[i]
style.rel = 'stylesheet'
if (scope._rawStyles === undefined) {
scope._rawStyles = []
}
scope._rawStyles.push([hrefs[i], style])
scope._styles.push(document.head.appendChild(style))
scope.$on('$destroy', this.clean_styles)
}
},
clean_styles: function () {
var removables = []
for (var key in scope._rawStyles) {
console.log('deleting style ' + scope._rawStyles[key][0])
scope._styles[key].parentNode.removeChild(scope._rawStyles[key][1])
removables.push(key)
}
scope._styles = scope._styles.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
scope._rawStyles = scope._rawStyles.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
},
script: function (inp) {
var hrefs = []
if (typeof inp === 'string') {
hrefs.push(inp)
} else {
hrefs = inp
}
scope._scripts = []
for (var i in hrefs) {
console.log('loading javascript: ' + hrefs[i])
var script = document.createElement('script')
if (!/^https?\:\/\//.test(hrefs[i])) {
script.type = 'text/javascript'
}
script.src = hrefs[i]
if (scope._rawScripts === undefined) {
scope._rawScripts = []
}
scope._rawScripts.push([hrefs[i], script])
scope._scripts.push(document.head.appendChild(script))
scope.$on('$destroy', this.clean_scripts)
}
},
clean_scripts: function () {
var removables = []
for (var key in scope._rawScripts) {
console.log('deleting script ' + scope._rawScripts[key][0])
scope._scripts[key].parentNode.removeChild(scope._rawScripts[key][1])
removables.push(key)
}
scope._scripts = scope._scripts.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
scope._rawScripts = scope._rawScripts.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
}
}
}])
中断路由用法示例:
route.js
...
when('/', {
templateUrl: 'hipermídia/check_insurance.template.html',
controller: 'pedidos_controller',
resolve: {
factory: function (Res) {
controllersAndServices(Res, {scripts: 'https://cdn.plot.ly/plotly-latest.min.js'})
}
}
}).
此时,如果您在控制器中使用 plotly,例如:
var data = [
{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}
];
Plotly.newPlot('myDivID', data);
您可能会得到类似 ReferenceError: Plotly is not defined
的结果。
如果你将它移开,通过同步调用,可能是 setTimeout,甚至只是 angular 的文档准备就绪,看到正确图表的可能性就会增加。
有点hacky,但我会loop/test如果Plotly
var存在于根路由中,每条需要库的路由都是其子路由(解析应用于子路由如果他们也注入 属性)。
类似下面的内容将在根路由中得到解决:
resolve: {
plotly: function () {
const resolvePlotly = function () {
while (typeOf Plotly) === 'undefined') {
return setTimeout(function () { resolvePlotly() }, 150)
}
return Plotly
}
return resolvePlotly()
}
}
我会将已解析的注入添加到该路由,并将其传递给子路由,这样依赖项仍会等待 Plotly
对象在 运行 任何依赖控制器之前定义.
您还可以编写一个工厂包装 Plotly
对象,returns 它可用时 inject/use 它而不是直接访问 Plotly
.
我有条件地为 load/unload javascript 和 css 写了一个包装器。它在路由解析部分被称为:
resolve: {
factory: function (Res) {
controllersAndServices(Res, {styles: 'estilos/check_insurance.css'})
}
}
它通常很有魅力。问题是,一些库,比如 Plotly 推迟创建它们的主变量,所以库在可用之前加载。结果,我收到 Plotly 未在我的控制器中定义的错误,然后它们消失了。 肯定 当我到达控制台时,Plotly 正在愉快地等着我。
我确实意识到我的自定义加载器可能会在更多的库中发生这种情况,但令人高兴的是,大多数库都太小而不会出现这个问题。 plotly 很大,可能需要数百甚至数千毫秒才能设置。
所以我需要等待 Plotly 在我的 resolve
中以某种方式被定义。你是怎么做到的?
图书馆:
res_service.js
angular.module('app').service('Res', ['$rootScope', function ($rootScope) {
var scope = $rootScope
scope._scripts = scope._scripts || []
scope._styles = scope._styles || []
scope._rawScripts = scope._rawScripts || []
scope._rawStyles = scope._rawStyles || []
return {
style: function (inp) {
var hrefs = []
if (typeof inp === 'string') {
hrefs.push(inp)
} else {
hrefs = inp
}
scope._styles = []
for (var i in hrefs) {
console.log('styling page with ' + hrefs[i])
var style = document.createElement('link')
if (!/^https?\:\/\//.test(hrefs[i])) {
style.type = 'text/css'
}
style.href = hrefs[i]
style.rel = 'stylesheet'
if (scope._rawStyles === undefined) {
scope._rawStyles = []
}
scope._rawStyles.push([hrefs[i], style])
scope._styles.push(document.head.appendChild(style))
scope.$on('$destroy', this.clean_styles)
}
},
clean_styles: function () {
var removables = []
for (var key in scope._rawStyles) {
console.log('deleting style ' + scope._rawStyles[key][0])
scope._styles[key].parentNode.removeChild(scope._rawStyles[key][1])
removables.push(key)
}
scope._styles = scope._styles.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
scope._rawStyles = scope._rawStyles.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
},
script: function (inp) {
var hrefs = []
if (typeof inp === 'string') {
hrefs.push(inp)
} else {
hrefs = inp
}
scope._scripts = []
for (var i in hrefs) {
console.log('loading javascript: ' + hrefs[i])
var script = document.createElement('script')
if (!/^https?\:\/\//.test(hrefs[i])) {
script.type = 'text/javascript'
}
script.src = hrefs[i]
if (scope._rawScripts === undefined) {
scope._rawScripts = []
}
scope._rawScripts.push([hrefs[i], script])
scope._scripts.push(document.head.appendChild(script))
scope.$on('$destroy', this.clean_scripts)
}
},
clean_scripts: function () {
var removables = []
for (var key in scope._rawScripts) {
console.log('deleting script ' + scope._rawScripts[key][0])
scope._scripts[key].parentNode.removeChild(scope._rawScripts[key][1])
removables.push(key)
}
scope._scripts = scope._scripts.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
scope._rawScripts = scope._rawScripts.filter(function (v) { return (removables.indexOf(v) !== -1)? true: false })
}
}
}])
中断路由用法示例:
route.js
...
when('/', {
templateUrl: 'hipermídia/check_insurance.template.html',
controller: 'pedidos_controller',
resolve: {
factory: function (Res) {
controllersAndServices(Res, {scripts: 'https://cdn.plot.ly/plotly-latest.min.js'})
}
}
}).
此时,如果您在控制器中使用 plotly,例如:
var data = [
{
x: ['giraffes', 'orangutans', 'monkeys'],
y: [20, 14, 23],
type: 'bar'
}
];
Plotly.newPlot('myDivID', data);
您可能会得到类似 ReferenceError: Plotly is not defined
的结果。
如果你将它移开,通过同步调用,可能是 setTimeout,甚至只是 angular 的文档准备就绪,看到正确图表的可能性就会增加。
有点hacky,但我会loop/test如果Plotly
var存在于根路由中,每条需要库的路由都是其子路由(解析应用于子路由如果他们也注入 属性)。
类似下面的内容将在根路由中得到解决:
resolve: {
plotly: function () {
const resolvePlotly = function () {
while (typeOf Plotly) === 'undefined') {
return setTimeout(function () { resolvePlotly() }, 150)
}
return Plotly
}
return resolvePlotly()
}
}
我会将已解析的注入添加到该路由,并将其传递给子路由,这样依赖项仍会等待 Plotly
对象在 运行 任何依赖控制器之前定义.
您还可以编写一个工厂包装 Plotly
对象,returns 它可用时 inject/use 它而不是直接访问 Plotly
.