• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

atinc / ngx-tethys / 07aa0f59-e5f9-4b7e-9755-2f67bea3c0d5

21 Apr 2025 10:25AM UTC coverage: 90.271% (+0.001%) from 90.27%
07aa0f59-e5f9-4b7e-9755-2f67bea3c0d5

Pull #3341

circleci

minlovehua
docs(cdk): merge imports
Pull Request #3341: refactor(all): resolve 30 circular denpendencies TINFR-1830

5614 of 6878 branches covered (81.62%)

Branch coverage included in aggregate %.

89 of 94 new or added lines in 38 files covered. (94.68%)

64 existing lines in 12 files now uncovered.

13370 of 14152 relevant lines covered (94.47%)

921.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

83.61
/src/image/image.directive.ts
1
import {
2
    Directive,
3
    ElementRef,
4
    InjectFlags,
5
    Input,
6
    OnChanges,
7
    OnInit,
8
    SimpleChanges,
9
    Injector,
10
    OnDestroy,
11
    AfterViewInit,
1✔
12
    inject
13
} from '@angular/core';
7✔
14
import { IThyImageDirective, IThyImageGroupComponent, THY_IMAGE_GROUP_COMPONENT } from './image.token';
7✔
15
import { ThyImageMeta } from './image.class';
7✔
16
import { ThyImageService } from './image.service';
7✔
17
import { coerceBooleanProperty } from 'ngx-tethys/util';
18

19
/**
4✔
20
 * thyImage: 预览图片指令,只可绑定到 img 标签上
21
 * @name img[thyImage]
22
 * @order 10
7✔
23
 */
24
@Directive({
25
    selector: 'img[thyImage]',
7✔
26
    exportAs: 'thyImage',
2✔
27
    host: {
28
        '(click)': 'onPreview($event)',
29
        class: 'thy-image',
30
        '[class.thy-image-disabled]': 'thyDisablePreview'
7✔
31
    }
32
})
9✔
33
export class ThyImageDirective implements IThyImageDirective, OnInit, OnChanges, AfterViewInit, OnDestroy {
9✔
34
    private thyImageService = inject(ThyImageService);
9✔
35
    private injector = inject(Injector);
7✔
36
    private elementRef = inject(ElementRef);
37

2✔
38
    /**
39
     * 图片地址
40
     */
41
    @Input() thySrc: string;
2✔
42

2✔
43
    /**
2✔
44
     * 预览图片地址
2✔
45
     */
2!
46
    @Input() thyPreviewSrc: string;
2✔
47

48
    /**
49
     * 图片原图地址
×
50
     */
51
    @Input() thyOriginSrc: string;
52

53
    /**
54
     * 图片附加信息,包含 { name: string, size?: string | number; }
12✔
55
     */
12!
56
    @Input() thyImageMeta: ThyImageMeta;
12✔
57

58
    /**
59
     * 是否禁止预览
60
     * @default false
4✔
61
     */
1✔
62
    @Input({ transform: coerceBooleanProperty }) thyDisablePreview: boolean;
63

3!
64
    /**
×
65
     * 是否自动计算图片资源大小
×
66
     */
×
67
    @Input({ transform: coerceBooleanProperty }) thyResolveSize = false;
68

69
    get previewable(): boolean {
70
        return !this.thyDisablePreview;
71
    }
72

×
NEW
73
    private parentGroup: IThyImageGroupComponent;
×
74

75
    ngOnInit(): void {
76
        this.getParentGroup();
77
    }
78

79
    ngAfterViewInit(): void {
3✔
80
        if (this.parentGroup) {
81
            this.addParentImage();
6✔
82
        }
83
    }
84

85
    getParentGroup() {
86
        while (true) {
87
            // 多层 thy-image-group 嵌套时,获取最外层 thy-image-group 下的所有图片
88
            const injector = this.parentGroup?.injector || this.injector;
3✔
89
            const parentGroup = injector.get(THY_IMAGE_GROUP_COMPONENT, null, InjectFlags.SkipSelf);
90
            if (!parentGroup) {
91
                break;
92
            }
7✔
93
            this.parentGroup = parentGroup;
2✔
94
        }
2✔
95
    }
96

97
    addParentImage() {
1✔
98
        setTimeout(() => {
99
            const parentElement: HTMLElement = this.parentGroup.element.nativeElement;
100
            const images = parentElement.querySelectorAll('img[thyImage]');
101
            const index = Array.prototype.indexOf.call(images, this.elementRef.nativeElement);
102
            if (index >= 0) {
103
                this.parentGroup.addImage(this, index);
104
            } else {
105
                this.parentGroup.addImage(this, this.parentGroup.images.length);
106
            }
1✔
107
        });
108
    }
109

110
    ngOnChanges(changes: SimpleChanges): void {
111
        const { thySrc } = changes;
112
        if (thySrc) {
113
            this.elementRef.nativeElement.src = thySrc.currentValue;
114
        }
115
    }
116

117
    onPreview(event: MouseEvent) {
118
        if (!this.previewable || event.button !== 0) {
119
            return;
120
        }
121
        if (this.parentGroup) {
122
            const previewAbleImages = this.parentGroup.images.filter(e => e.previewable);
123
            const previewImages = previewAbleImages.map(e => ({
124
                src: e.thyPreviewSrc || e.thySrc,
125
                ...e.thyImageMeta,
126
                origin: {
127
                    src: e.thyOriginSrc
128
                }
129
            }));
130
            const startIndex = previewAbleImages.findIndex(el => this === el);
131
            this.thyImageService.preview(previewImages, {
132
                startIndex,
133
                resolveSize: this.thyResolveSize
134
            });
135
        } else {
136
            const previewImages = [
137
                {
138
                    src: this.thyPreviewSrc || this.thySrc,
139
                    ...this.thyImageMeta,
140
                    origin: {
141
                        src: this.thyOriginSrc
142
                    }
143
                }
144
            ];
145
            this.thyImageService.preview(previewImages, { resolveSize: this.thyResolveSize });
146
        }
147
    }
148

149
    ngOnDestroy(): void {
150
        if (this.parentGroup) {
151
            const index = this.parentGroup.images.findIndex(item => item === this);
152
            this.parentGroup.removeImage(index);
153
        }
154
    }
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc