我有一个相当简单的函数,它返回一个jQuery .ajax()的承诺:
CLAW.controls.validateLocation = function(val, $inputEl) {
return $.ajax({
url: locationServiceUrl + 'ValidateLocation/',
data: {
'locationName': val
},
beforeSend: function() {
$inputEl.addClass('busy');
}
}).done(function(result) {
// some success clauses
}).fail(function(result) {
// some failure clauses
}).always(function() {
// some always clauses
});
}
Run Code Online (Sandbox Code Playgroud)
在大多数情况下,这个新的promises接口就像一个梦想,并在使用jQuery的.ajax()时很好地消除了回调金字塔.但是,我不能为我的生活弄清楚如何使用Jasmine和/或Sinon正确测试这些承诺:
所有Sinon的文档都假设您正在使用旧式回调; 我没有看到如何将它与promises/deferred一起使用的单个示例
当尝试使用茉莉花或兴农窥探窥探$阿贾克斯,间谍有效覆盖的承诺,所以其done
,fail
和always
条款不再对AJAX功能的存在,因此从来没有承诺解决和扔一个错误,而不是
我真的很喜欢一个或两个如何用上述测试库测试这些新的jQuery .ajax()promises的例子.我已经相当强烈地搜索了'网,并没有真正挖掘任何东西这样做.我找到的一个资源是使用Jasmine.ajax提到的,但我想尽可能避免这种情况,因为Sinon提供了大部分开箱即用的相同功能.
我们假设这是我的config.js或main.js:
require.config({
// paths are analogous to old-school <script> tags, in order to reference js scripts
paths: {
jquery: "libs/jquery-1.7.2.min",
underscore: "libs/underscore-min",
backbone: "libs/backbone-min",
jquerymobile: "libs/jquery.mobile-1.1.0.min",
jquerymobilerouter: "libs/jquery.mobile.router.min"
},
// configure dependencies and export value aliases for old-school js scripts
shim: {
jquery: ["require"],
underscore: {
deps: ["jquery"],
exports: "_"
},
backbone: {
deps: ["underscore", "jquery"],
exports: "Backbone"
},
jquerymobilerouter: ["jquery", "backbone", "underscore"],
jquerymobile: ["jquery", "jquerymobilerouter", "backbone", "underscore"]
}
});
require(["jquery", "backbone", "underscore", "app/app.min", "jquerymobilerouter", "jquerymobile"], function ($, Backbone, _, …
Run Code Online (Sandbox Code Playgroud) 假设我的Express应用程序上有一些GET路由:
// music albums
app.get('/api/albums', routes.albums.getAlbums);
app.get('/api/albums/:id', routes.albums.getAlbum);
app.get('/api/albums/artwork', routes.albums.getAlbumArtwork);
Run Code Online (Sandbox Code Playgroud)
我试图使用以下jQuery AJAX片段来击中它们:
$("#retrieveAlbumArtwork").on("click", function() {
$.ajax({
url: "api/albums/artwork",
type: "GET",
data: {
artist: $("#albumArtist").val(),
title: $("#albumTitle").val()
},
// ... callbacks and such
Run Code Online (Sandbox Code Playgroud)
出于某种原因,此调用使用/:id
参数而不是显式/artwork
路由来命中第二个处理程序.像这样交换它们使它们按预期运行:
// music albums
app.get('/api/albums', routes.albums.getAlbums);
app.get('/api/albums/artwork', routes.albums.getAlbumArtwork);
app.get('/api/albums/:id', routes.albums.getAlbum);
Run Code Online (Sandbox Code Playgroud)
有人能解释为什么会发生这种情况吗?我认为Express会足够聪明地识别一个id param(/albums/23453243
)与一个querystring(/albums/artwork?artist=artistName&title=albumTitle
)并适当地路由,但这似乎不是这样的吗?
当然,有很多资源用于实现对SEO友好版本的AngularJS应用程序.尽管阅读了所有这些内容,但我仍然对一些事情有点不清楚,特别是关于hashbang和HTML5模式模型之间的区别:
对于hashbang(#!
或"HTML4")应用程序,location
提供程序提供以下设置:
$location.hashPrefix('!');
Run Code Online (Sandbox Code Playgroud)
HTML5模式也需要此设置吗?为什么或者为什么不?
对于HTML5模式应用,页面中meta
包含以下标记index.html
:
<meta name="fragment" content="!">
Run Code Online (Sandbox Code Playgroud)
hashbang应用程序也需要这个元标记吗?为什么或者为什么不?
使用HTML5模式,我的网址类似于:
http://sample.com/landing/home
Run Code Online (Sandbox Code Playgroud)
即使使用meta
我指定的#2中的标记index.html
,我仍然无法像抓取工具那样导航到我的网址,例如:
http://sample.com/#!/landing/home
Run Code Online (Sandbox Code Playgroud)
这是正常的吗?在添加location
提供程序设置和/或meta
标记后,我是否希望能够导航到我的应用程序hashbang样式(如果它是HTML5模式应用程序)?
最重要的是,我想我实际的问题是:什么是特别需要的HTML5模式爬行,有什么具体要求hashbang式爬行?它们如何重叠?另外,如果没有生成/可用的hashbang风格的路由,HTML5模式配置如何在幕后实际工作?
请注意,这些问题与生成/提供快照的问题是分开的,我通常理解这一点.
对于经典的hashbang风格的应用程序,AngularJS SEO友好的配置通常是有意义的,但对于HTML5模式,我有点困惑.会喜欢一些清晰度.
我正在使用Backbone进入更大规模的数据结构,并遇到通过CompositeViews很好地表示数据的场合; 也就是说,CollectionViews在它们周围增加了"添加绒毛",例如标题,按钮等.
但是,我在将CompositeViews嵌套在一起时遇到了很多困难.使用CompositeView上的标准itemView属性来渲染另一个CompositeView似乎根本没有触发.
假设我有一个父ItemView,如此实例化(遵循Derick Bailey的例子 ;假设这个顶级是fetch()
调用集合的初始值):
var User = Backbone.Model.extend({});
var UserCollection = Backbone.Collection.extend({
model: User
});
var userList = new UserCollection(userData);
var schedulerCompositeView = new SchedulerCompositeView({
collection: userList
});
schedulerCompositeView.render();
this.ui.schedulerWidget.html(schedulerCompositeView.el);
Run Code Online (Sandbox Code Playgroud)
而SchedulerCompositeView看起来像这样:
return Backbone.Marionette.CompositeView.extend({
template: Handlebars.compile(schedulerCompositeViewTemplate),
itemView: SchedulerDetailCompositeView,
appendHtml: function (collectionView, itemView) {
collectionView.$("#schedulerGroups").append(itemView.el);
}
});
Run Code Online (Sandbox Code Playgroud)
最后,SchedulerDetailCompositeView:
return Backbone.Marionette.CompositeView.extend({
template: Handlebars.compile(schedulerDetailCompositeViewTemplate),
itemView: SchedulerDetailItemView,
appendHtml: function (collectionView, itemView) {
collectionView.$("#schedulerDetailStops").append(itemView.el);
}
});
Run Code Online (Sandbox Code Playgroud)
SchedulerDetailCompositeView永远不会被实例化; 事实上,它的appendHtml()
方法似乎永远不会发生.
显然,这里缺少一些其他信息; 显然,目的是将一个集合/模型传递给SchedulerDetailCompositeView,但由于嵌套的CompositeViews,我不确定这样做的正确方法是什么.
作为参考,这里是我想要实现的结构的粗略模型; 如果有可能比嵌套的CompositeViews更好地实现这个目标,我当然都是耳朵:
在版本2.0.2中grunt-browserify
,browserify-shim
已从模块本身中删除并转换为用作a transform
,而不是直接option
执行grunt-browserify
任务.
使用垫片的旧版本grunt-browserify
看起来如此:
'libs-dev': {
src: [path.join('<%= config.dirs.browserLibs %>', 'angular', 'angular.js')],
dest: path.join('<%= config.dirs.dest.dev %>', 'js', 'libs.js'),
options: {
shim: {
angular: {
path: path.join('<%= config.dirs.browserLibs %>', 'angular', 'angular.js'),
exports: 'angular'
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这很好用,并在libs.js
模块周围生成一个包装器:
require=(function(e,t,n){function i(n,s){if(!t[n]){if(!e[n]){var o=typeof require=="function"&&require;if(!s&&o)return o(n,!0);if(r)return r(n,!0);throw new Error("Cannot find module '"+n+"'")}var u=t[n]={exports:{}};e[n][0].call(u.exports,function(t){var r=e[n][1][t];return i(r?r:t)},u,u.exports)}return t[n].exports}var r=typeof require=="function"&&require;for(var s=0;s<n.length;s++)i(n[s]);return i})({"angular":[function(require,module,exports){
module.exports=require('i10PRm');
},{}],"i10PRm":[function(require,module,exports){
(function(global){(function browserifyShim(module, exports, define, browserify_shim__define__module__export__) {
browserify_shim__define__module__export__(typeof angular …
Run Code Online (Sandbox Code Playgroud) 我们知道,您可以npm run
通过向scripts
您的package.json
:添加哈希来运行任意命令:
"scripts": {
"build-js": "browserify browser/main.js | uglifyjs -mc > static/bundle.js"
}
Run Code Online (Sandbox Code Playgroud)
然后将运行npm run build-js
.
您还可以将这些命令移到单独的脚本中,例如bash脚本,如下所示:
"scripts": {
"build-js": "bin/build.sh"
}
Run Code Online (Sandbox Code Playgroud)
由于Windows无法运行bash脚本,因此显然本身不能在Windows上运行.您可以安装bash端口等,但我希望能够使用某种本机Windows构造来执行相同的操作.
我尝试了一些其他方法,包括使用child_process.exec
从标准节点脚本文件中运行任意命令:
"scripts": {
"build-js": "node bin/build.js"
}
Run Code Online (Sandbox Code Playgroud)
但我注意到child_process
相对较大/密集型操作的窒息,使其使用起来难以置信.
是否有特定于Windows(甚至更好,跨平台)的方法将这些package.json
npm run
脚本移动到单独的文件中?最好是不需要bash的?
我正在尝试使用Karma,Karma-Jasmine和Karma-Browserify在Angular/Browserify项目上设置单元测试.我在Windows机器上,供参考.karma-cli
是我的全球NPM路径上,并且karma
,karma-jasmine
,karma-browserify
,和browserify
都是本地NPM安装,使用-D
.
我正在尝试引入一个spec文件,看起来像:
var PhoneListCtrl = require('../../../public/js/app/controllers/phone-list');
describe('PhoneListCtrl', function() {
var scope,
ctrl;
beforeEach(function() {
scope = {};
ctrl = new PhoneListCtrl(scope);
});
it('should create "phones" model with 3 phones', function() {
expect(scope).not.toBe(undefined);
});
});
Run Code Online (Sandbox Code Playgroud)
我每次都会收到以下错误:
Uncaught Error: Cannot find module 'Cc/gGH'
Run Code Online (Sandbox Code Playgroud)
克隆下面的repos,安装karma和所有插件,并尝试运行他们的示例测试套件后,我得到了完全相同的错误:
https://github.com/xdissent/karma-browserify
https://github.com/waye929/angular-browserify
我究竟做错了什么?正确找到了测试规范模块,并且业力似乎正在寻找所有必要的插件/预处理器,但似乎karma-browserify require
每次都会在规范中对语句进行绊倒,原因我无法理解.
我已经多次卸载并重新安装业力和所有相关插件,但无济于事.
假设我有一个包含带有ng-include
指令的元素的模板:
<div ng-include src="'templates/top-promo-content.html'"></div>
Run Code Online (Sandbox Code Playgroud)
我正在尝试将所有模板简化为我们构建的应用程序JS(使用browserify
和brfs
转换),从概念上讲,它看起来像:
<div ng-include src="fs.readFileSync('./templates/top-promo-content.html', 'utf8')"></div>
Run Code Online (Sandbox Code Playgroud)
哪个最终会导致:
<div ng-include src="<ul><li>list item</li></ul>"></div>
Run Code Online (Sandbox Code Playgroud)
有没有办法,而不是使用模板URL,而不是使用ng-include
原始或编译的HTML?如果没有,是否有另一种角度的替代方案可以让我实现这一点,或者作为某种包含或部分,但是能够包含原始/编译的HTML?
javascript templates angularjs browserify angularjs-directive
我发现各种Deferred/promise库的文档通常涵盖非常简单的用例,例如链接1或2个函数/方法,并导致解决或拒绝成功或错误.
然而,当涉及到更复杂的用例(5个以上的函数/方法链;嵌套的Deferreds;从其他Deferreds中返回promise)时,我空手而归并变得非常沮丧.
比方说,我有一个包含2个嵌套函数的函数.每个子函数都返回一个promise,我希望父函数返回子函数的成功/失败结果:
var saveUser = function(user) {
var saveNewUser = function(user) {
var deferred = when.defer();
user.save(function (err) {
if (err) {
deferred.reject();
}
else {
// forcing a rejection here for testing purposes
deferred.reject(6);
}
});
return deferred.promise;
}
var supplyUserCollections = function() {
var deferred = when.defer();
deferred.reject();
return deferred.promise;
}
return saveNewUser(user).then(supplyUserCollections(), function() {
console.log('failed to save new user');
}).then(function(data) {
console.log('succeeded to do everything');
}, function() {
console.log('failed to seed new user collections');
});
} …
Run Code Online (Sandbox Code Playgroud) javascript ×7
node.js ×5
angularjs ×3
browserify ×3
jquery ×3
jasmine ×2
api ×1
asynchronous ×1
backbone.js ×1
bash ×1
commonjs ×1
express ×1
get ×1
gruntjs ×1
html5 ×1
karma-runner ×1
marionette ×1
module ×1
npm ×1
promise ×1
requirejs ×1
routing ×1
seo ×1
sinon ×1
templates ×1
unit-testing ×1
web-crawler ×1
windows ×1