我正在Angular中编写一个REST应用程序,我想为它编写单元测试(当然!).我有一个控制器,它从json中的REST服务获取博客文章列表,并将摘要放入$ scope,因此我可以在视图中显示它们.
起初,博客帖子只是显示为文本<p>Blog body</p>,而不是渲染为解析的HTML,直到我发现你可以将ng-bind-html与$ sce服务结合使用.这在正确显示博客文章方面现在可以正常工作.
单元测试时会出现问题.我试图用一些HTML模拟一个json响应,然后测试我的控制器是否正确处理HTML.这是我的代码:
.controller( 'HomeCtrl', function HomeController( $scope, $http, $sce ) {
$scope.posts = {};
$http.get('../drupal/node.json').success(function (data) {
var posts;
posts = data.list;
for(var i = 0; i < posts.length; i ++) {
posts[i].previewText = $sce.trustAsHtml(posts[i].body.summary);
posts[i].created = posts[i].created + '000'; // add milliseconds so it can be properly formatted
}
$scope.posts = posts;
});
})
Run Code Online (Sandbox Code Playgroud)
describe('HomeCtrl', function() {
var $httpBackend, $rootScope, $sce, createController;
beforeEach(inject(function ($injector) {
// Set …Run Code Online (Sandbox Code Playgroud) 我正在为AngularJS指令编写测试,该指令<textarea>在按下某些键时触发事件.根据我的手动测试,一切正常.我想要做得很好,也有一个完整的单元测试套件,但是我遇到了一个我自己无法解决的问题:
我想在我的测试中发送一个特定keyCode的triggerHandler()调用,但我找不到一种方法来指定实际工作的密钥.我知道有关构建和发送具有特定数据的事件的主题的许多问题和答案,但它们都不适用于我的设置:
var event = document.createEvent("Events");
event.initEvent("keydown", true, true);
event.keyCode = 40; // in debugging the test in Firefox, the event object can be seen to have no "keyCode" property even after this step
textarea.triggerHandler(event); // my keydown handler does not fire
Run Code Online (Sandbox Code Playgroud)
奇怪的是,我可以在Chrome中键入控制台中的前3行,并看到正在创建事件时将keyCode属性设置为40.所以看起来应该可以正常工作.
此外,当我像这样调用最后一行时,textarea.triggerHandler("keydown");它工作,并触发事件处理程序.然而,没有keyCode合作,所以这是毫无意义的.
我怀疑它可能与针对DOM运行的测试的性质有关,该DOM与浏览器中运行的常规页面不同.但我无法弄清楚!
我有一个样式表,设置像这样的css过渡属性(为简洁省略了前缀版本):
transition: opacity 1s;
Run Code Online (Sandbox Code Playgroud)
然后我在页面上有许多元素,我希望transition-delay通过JavaScript 修改每个元素的属性,以产生交错效果.我正在使用jQuery:
$(element).css('transition-delay', delay + 's');
Run Code Online (Sandbox Code Playgroud)
然而,上述代码并没有内嵌添加transition-delay: Xs到元素.相反,它导致:
<div style="transition: Xs;">
Run Code Online (Sandbox Code Playgroud)
但这很好,因为它按预期工作.不知何故,浏览器知道这transition: Xs真的意味着只需设置transition-delay为Xs并保持其余部分不变.
如果我现在获得该元素的内联样式$(element).attr('style'),然后将其重新应用于元素,$(element).attr('style', style)则HTML看起来完全相同,但现在转换完全覆盖了其他属性,并且基本上将元素的转换值设置为all Xs ease 0s.
// HTML before - working
<div style="transition: Xs">
// then I do this
var style = $(el).attr('style');
$(el).attr('style', style);
// HTML after - broken!
<div style="transition: Xs">
Run Code Online (Sandbox Code Playgroud)
正是我所描述的JSFiddle:http://jsfiddle.net/7vp8m/4/
我正在制作一个可重复使用的Angular2组件,我希望用户能够指定一个模板字符串或templateUrl,然后该组件将通过属性或通过某种服务方法设置该组件.
// somewhere else in app
myService.setTemplateUrl('path/to/template.html');
// directive definition
function myDirective(myService) {
return {
template: function(element, attrs) {
return attrs.templateUrl || myService.getTemplateUrl();
}
// ...
};
}
Run Code Online (Sandbox Code Playgroud)
@Component({
selector: 'my-component',
template: '...' // cannot see `mySerivce` from here, nor access the element attributes
})
export class MyComponent {
constructor(private myService: MyService) {}
}
Run Code Online (Sandbox Code Playgroud)
虽然我的问题特别涉及如何实现动态模板,但更广泛的问题是是否可以从各种装饰器访问注入的依赖项实例.
我有一个TypeScript项目,我正在捆绑Webpack.它是我正在编写的开源库的demo/docs应用程序,所以我想将一些源代码显示为文档的一部分.
在我的webpack配置中,我有:
loaders: [
{ test: /\.ts$/, loader: 'ts'},
{ test: /\.css$/, loader: 'style!raw' },
{ test: /\.html/, loader: 'html' }
]
Run Code Online (Sandbox Code Playgroud)
这适用于转换和捆绑我的TypeScript文件.在我的一个应用程序组件中,我这样做:
basicCodeT: string = require('./basic-example-cmp.html');
basicCodeC: string = require('!raw!./basic-example-cmp.ts');
Run Code Online (Sandbox Code Playgroud)
将源代码加载到我想要在文档中显示的字符串中.
正如您所看到的,!在第二行中有一个领先者,我发现它似乎从配置中"绕过"默认加载器并将原始TypeScript作为字符串加载.
在我的开发版中,这可行,但是当我使用UglifyJsPlugin和OccurrenceOrderPlugin进行"生产"构建时,我得到以下输出:
ERROR in ./demo/src/basic-example-cmp.html
Module build failed:
@ ./demo/src/demo-app.ts 24:26-61
Run Code Online (Sandbox Code Playgroud)
这对应于我尝试要求原始TypeScript的源代码行.
所以,我想basic-example-cmp.ts通过TS编译器作为应用程序构建的一部分,但也想要在应用程序中将其作为原始文本.
我的问题是:在特定的需求案例中,是否有正确的方法告诉webpack"忽略"加载器?
我的前置方式是!正确的吗?这是一个黑客?
事实证明我的问题仅仅是由于Webpack处理HTML模板的方式 - 它不喜欢Angular 2模板语法,请参阅:https://github.com/webpack/webpack/issues/992
假设我有一个组件:
@Component({
selector: 'foo',
template: '<div>foo</div>'
})
export class Foo {}
Run Code Online (Sandbox Code Playgroud)
我在另一个组件中使用它:
<foo>
<h1>some inner HTML</h1>
</foo>
Run Code Online (Sandbox Code Playgroud)
我怎样才能知道Foolight DOM中是否有任何子元素?
我想要了解<h1>some inner HTML</h1>.
选项1 - @ContentChildren():这不能用于查询任意元素; 目前只能#foo以这种方式查询Angular 2组件或变量().如果我可以避免,我不想将变量附加到内部元素.
选项2 - elementRef.nativeElement:我可以注入ElementRef到Foo组件,但是通过在组件已实例化(在构造)时,内部元件已经被移除,并且这将是空的.在生命周期的后期(例如ngAfterViewInit()),内部元素将只是阴影DOM(即<div>foo</div>).
我失踪的任何其他方法?
用例
为了给出我想要这样做的一些背景,我正在创建一个具有默认模板的库组件,如果用户决定,可以用自定义模板替换.所以我的默认模板如下所示:
<div *ngIf="hasTemplate"><ng-content></ng-content></div>
<div *ngIf="!hasTemplate"><!-- the default template --></div>
Run Code Online (Sandbox Code Playgroud)
我需要一些方法来设置hasTemplate,以true是否有内部HTML <foo>..</foo>标记.
我正在使用 Electron 构建一个项目,并使用 Webpack 构建(Angular 2)渲染流程应用程序。
在这个应用程序中,我需要require在运行时动态处理一些在构建时不存在的文件。代码如下所示:
require("fs").readdirSync(this.path).forEach(file => {
let myModule = require(path.join(this.path, file));
// do stuff with myModule
});
Run Code Online (Sandbox Code Playgroud)
问题是 Webpack 编译器会将require()调用转换为自己的,__webpack_require__()并且在运行时,它会在自己的内部模块注册表中查找动态“myModule”文件,当然不会找到它。
我试过使用“externals”配置选项,但由于这是一个动态需求,它似乎没有被“externals”处理。
还有其他人成功解决了这个问题吗?
我有一个父节点的webroot路径,想返回该节点的子节点。例如,使用https://demo.getmesh.io/api/v1/demo/webroot/images/只会产生节点本身。
javascript ×3
angular ×2
angularjs ×2
jasmine ×2
karma-runner ×2
typescript ×2
unit-testing ×2
webpack ×2
css ×1
css3 ×1
electron ×1
gentics-mesh ×1
html ×1
node.js ×1